What is the correct method to implement a infinitely running task which executes an Async BigJob()
? and can be stopped upon request
Hint: I am trying to learn [a] new method(s) to update my existing strategy.
I have this simple program (a tester) which has an Start and Stop button.
When Start pressed, I am starting the tester which is going to find and test available devices in range and test the hell our of them in infinite amount of rounds until the user presses the Stop button.
The important point is, the main process/action/bigJob() is and awaitble asynchronous process.
So I would pseudo code the whole thing as
Start
Round 1 starts
Async Main job starts
Async connect
Async Read
Async Write
Async disconnect
Nobody cancelled me yet
Round 1 finishes
Round 2 starts
.
.
.
Round 2 finishes
Round 3 starts
.
Stop pressed, hence break out.
Stop
So I am using BackgroundWorker
to implement the infinite loop and Async/Await
for the Connect, read, write and disconnect that I have written in C#
under .Net 4.5
Since my sub-tasks such as Connect and .etc are async
then my main task is async
and pressing the Stop button stops my process since it eliminates the infinite while
loop that I have with having
while (!bw.CancellationPending)
{
await MainTask();
...
}
but it doesn't fire the BackgroundWorker_RunWorkerCompleted
event, which doesn't do me any harm HOWEVER it's killing me since the background worker doesn't work as it's supposed to and I just keep thinking "there should be a better way!".
So, I have been reading about so many new ideas, like why to use BackgroundWorker
at all now that we have Async/await
. Some were saying use Task.Run()
it's magical. I even read recommendations and blogs about this godsend TPL Dataflow that I have never heard of. And so far I haven't found a method which is as structured, documented and layed-out as a BackgroundWorker
. (unless it's such simple or a one liner which doesn't even need documentation or .etc) So, guys, what is the solution for this. Or better way to ask:
What is the correct method to implement a infinitely running task which executes an Async BigJob()
? and can be stopped upon request
Or in other words, an infinite loop is a loop in which the test condition does not evaluate to false and the loop continues forever until an external force is used to end it. You can create an infinite loop: Using for loop.
In each iteration you calculate a number (the sum of the squares of the digits or the previous number). You can put all those numbers in a Set. If in some iteration you calculate a number that is already in that Set, you know that you are stuck in an infinite loop.
Basically, the infinite loop happens when the condition in the while loop always evaluates to true. This can happen when the variables within the loop aren't updated correctly, or aren't updated at all.
You should use CancellationTokenSource
. But don't pass the Token
to the Task.Run
method and don't throw an exception. Simply check if cancellation was requested and then stop.
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
Task.Run(
async () =>
{
while (!ct.IsCancellationRequested)
{
await ConnectAsync();
await ReadAsync();
await WriteAsync();
await DisconnectAsync();
}
});
cts.Cancel();
When you pass a CancellationToken
to the Task itself(Task.Run(async () => ..., ct)
), you can't use it inside the delegate. It will only cancel the task if cancellation was called before the task started running. After it has begun, calling Cancel
won't have any effect.
Create a CancellationTokenSource and pass its Token to the async task. This will allow you to signal to your async tasks that cancellation is requested. More info: http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
I would strongly recommend everybody to have a read about three different methods of Asynchronous Programming Patterns and the use of the recent and preferred method Task-based Asynchronous Pattern (TAP)
Asynchronous Programming Model (APM)
Describes the legacy model that uses the IAsyncResult interface to provide asynchronous behavior. This model is no longer recommended for new development.Event-based Asynchronous Pattern (EAP)
Describes the event-based legacy model for providing asynchronous behavior. This model is no longer recommended for new development.Task-based Asynchronous Pattern (TAP)
Describes the new asynchronous pattern based on the System.Threading.Tasks namespace. This model is the recommended approach to asynchronous programming in the .NET Framework 4 and later versions.
Thanks to @SKall for pointing me to the right direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With