C Run Continue Longoperation With Bothering Rest of Executions

  • Updated date Jun 05, 2020
  • 66.1k
  • 5

We often come across a scenario where we need to run some function for a long time where this function would react on some trigger and then run some code logic. This is where we need to apply a long running task. This task stays active and responds to a specific trigger. In today's article we will look at creating such a long running task. We will pass to it the function that needs to run and when the trigger is activated a single run of the function will be executed.

Introduction

We often come across a scenario where we need to run some function for a long time where this function will react on some trigger and then run some code logic. This is where we need to apply a long running task. This task stays active and responds to a specific trigger. In today's article we will look at creating such a long running task. We will pass to it the function that needs to run and when the trigger is activated a single run of the function will be executed.

The Long Running Task

In this example, we have created a class as below,

  1. using  System;
  2. using  System.Threading;
  3. using  System.Threading.Tasks;
  4. namespace  LongRunningTask
  5. {
  6. public class  LongTask
  7.     {
  8. readonly  CancellationTokenSource cts = new  CancellationTokenSource();
  9. readonly  AutoResetEvent are = new  AutoResetEvent( false );
  10. public  async Task StartTask( int  value, Func< int ,Task> act)
  11.         {
  12. while  ( true )
  13.             {
  14. if  (cts.IsCancellationRequested) throw new  OperationCanceledException();
  15.                 await act(value);
  16.                 are.WaitOne();
  17.                 value++;
  18.             }
  19.         }
  20. public void  NextStep()
  21.         {
  22.             are.Set();
  23.         }
  24. public void  CancelTask()
  25.         {
  26.             cts.Cancel();
  27.         }
  28.     }
  29. }

In this class, we see that we have a function called Start Task which accepts some initial value that will be used by the executing function. The second parameter is the function itself. This function has an input type of integer (which we are using only as an example here) and the return type of a task. If we will be running a self-isolated task that returns no values, we can simply use an Action delegate as well. We then start an endless loop and do the following steps inside it,

  1. Add a cancellation check in case we want to cancel the long running task
  2. Execute the function
  3. Block further execution using an AutoResetEvent primitive

Now, when we start the task, the passed function will execute once and stop until a signal is received via the "NextStep" function to continue. Once this signal is received, we will call the Set function on the AutoResetEvent primitive and run the function one more time. In this example, we simply increment the input integer value by one. In a real-life scenario, inputs can be updated based on requirements. Also, we have another function called "CancelTask". When called, we use a CancellationTokenSource to cancel the task.


Example of using the Long Running Task

For demonstration purposes, I have created a Windows Form .NET Core 3.1 application. This application has three labels we will use to start the task, run the next step in the loop and finally cancel the task. For some strange reason, it seems that buttons are missing from the toolbar and hence I decided to use labels. Below is the layout and code for the application,

Create A Long Running Task In C#.NET Core

  1. using  System;
  2. using  System.Diagnostics;
  3. using  System.Threading.Tasks;
  4. using  System.Windows.Forms;
  5. namespace  LongRunningTask
  6. {
  7. public  partial class  Form1 : Form
  8.     {
  9.         LongTask lt;
  10. public  Form1()
  11.         {
  12.             InitializeComponent();
  13.         }
  14. private void  Form1_Load( object  sender, EventArgs e)
  15.         {
  16.             SetText(false , false );
  17.         }
  18. private  async void  StartTask_Click( object  sender, EventArgs e)
  19.         {
  20.             SetText(true , true , false );
  21. try
  22.             {
  23.                 lt =new  LongTask();
  24.                 await Task.Run(() => lt.StartTask(1, LongRunningTask));
  25.             }
  26. catch
  27.             {
  28.                 Debug.WriteLine("An error occured in the application" );
  29.             }
  30.         }
  31. private void  StopTask_Click( object  sender, EventArgs e)
  32.         {
  33.             lt.CancelTask();
  34.             NextTask_Click(this , null );
  35.             SetText(false , false );
  36.         }
  37. private void  NextTask_Click( object  sender, EventArgs e)
  38.         {
  39.             lt.NextStep();
  40.         }
  41. private void  SetText( bool  nextRun, bool  stopTask, bool  startTask = true )
  42.         {
  43.             NextRun.Enabled = nextRun;
  44.             StopTask.Enabled = stopTask;
  45.             StartTask.Enabled = startTask;
  46.         }
  47. private  async Task LongRunningTask( int  value)
  48.         {
  49.             Debug.WriteLine($"Task executed = {value}" );
  50.             await Task.Delay(1000);
  51.         }
  52.     }
  53. }

As you can see we have a function called "LongRunningTask" which simply writes the value of an integer to the output window. We pass this function to the StartTask function of the LongTask class. This function is executed once and then it waits for the user to either click the label "Run next Loop Item" or the "Stop Task" label. If the "Run next Loop Item" label is clicked, the function is executed one more time and waits again. If the "Stop Task" label is clicked, the running loop is cancelled.

We can see this in action as below,

Create A Long Running Task In C#.NET Core

Summary

In this article, we looked at how to create a generic long running task class to which we can pass a function which executes on a trigger, which is also run by the client. I have used a simple Windows form example as the client in this article. However, this generic LongTask class can be used by other clients like other classes, services etc. This can be used to create a sort of service which is processing a list. We will call the function via the Long running task class and wait until it is completed. When the function is completed and the first item is processed, we can make a call back to the client class, which will then trigger the function again and this time the second item is executed. This model runs one function at one time. If we wanted to increase it to multiple tasks at the same time, we can use the Task Parallel Library and "Wait All" function for that.

nielsendrelvel.blogspot.com

Source: https://www.c-sharpcorner.com/article/create-a-long-running-task-in-c-sharp-net-core/

0 Response to "C Run Continue Longoperation With Bothering Rest of Executions"

ارسال یک نظر

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel