I am looking for a simple way of calling multiple asynchronous operation with abili开发者_如何学编程ty to cancel them:
var cancelTask = new ManualResetEvent(false);
IAsyncResult ar = StartAsyncBatch(cancelTask);
int resp = WaitHandler.WaitAny({ar.AsyncWaitHandle, cancelTask});
How I have to build StartAsyncBatch? Should it be derived class
class StartAsyncBatch : IAsyncResult
The brief answer is you can cancel the waiting tasks via corresponding CancellationToken built by CancellationTokenSource. Here is an example.
var tokenSource = new CancellationTokenSource();
var task = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
if (tokenSource.IsCancellationRequested)
{
//you know the task is cancelled
//do something to stop the task
//or you can use tokenSource.Token.ThrowIfCancellationRequested()
//to control the flow
}
else
{
//working on step i
}
}
}, tokenSource.Token);
try
{
task.Wait(tokenSource.Token);
}
catch (OperationCanceledException cancelEx)
{
//roll back or something
}
//somewhere e.g. a cancel button click event you call tokenSource.Cancel()
Things are a little different when you are dealing with a few tasks. Firstly you need to know when cancelling a task, will other tasks continue? If yes, you need to create different cancellation tokens for different tasks and handle the cancellation independently. Otherwise they can share the same cancellation token. Different requirement causes different cancellation handling policy.
If you are using .NET 3.5 or 4.0 I would recommend to use Task Parallel Library (TPL). It is much easier to control your tasks and you have much more flexibility with controlling/canceling tasks. Check this link Task Parallelism If you use TPL and you need to cancel all or any of the tasks you will need to create CancellationToken Here is an example on how to do it Task Cancellation.
And yes you can use TPL in .NET 3.5. Here is the link how to do that Reactive Extensions and Parallel Extensions Basically you will need to install Reactive Extensions (Rx)
Danny's code is logically correct, but actually does not run. When WaitHandle.WaitAll() is called, the program is blocked (including the two tasks). One can create a new thread to wait all events to be signalled:
Thread t = new Thread(() =>
{
WaitHandle.WaitAll(handles);
MessageBox.Show("Both Threads are finished");
});
t.Start();
精彩评论