我正在寻找一种简单的方法来调用多个异步操作并取消它们:
var cancelTask = new ManualResetEvent(false);
IAsyncResult ar = StartAsyncBatch(cancelTask);
int resp = WaitHandler.WaitAny({ar.AsyncWaitHandle, cancelTask});
我如何构建StartAsyncBatch?它应该是派生类
class StartAsyncBatch : IAsyncResult
答案 0 :(得分:8)
简要回答是您可以通过CancellationTokenSource构建的相应CancellationToken取消等待任务。这是一个例子。
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()
当你处理一些任务时,情况会有所不同。首先,你需要知道取消任务的时间,其他任务会继续吗?如果是,您需要为不同的任务创建不同的取消令牌并独立处理取消。否则,他们可以共享相同的取消令牌。不同的要求会导致不同的取消处理政策。
答案 1 :(得分:2)
如果您使用的是.NET 3.5或4.0,我建议使用任务并行库(TPL)。控制任务要容易得多,控制/取消任务的灵活性也大大提高。检查此链接Task Parallelism如果您使用TPL,则需要取消创建所需的全部或任何任务.RelationlationToken以下是有关如何执行此操作的示例Task Cancellation。
是的,你可以在.NET 3.5中使用TPL。以下是如何执行此操作的链接Reactive Extensions and Parallel Extensions基本上您需要安装Reactive Extensions(Rx)
答案 2 :(得分:0)
Danny的代码在逻辑上是正确的,但实际上并没有运行。调用WaitHandle.WaitAll()时,程序被阻止(包括两个任务)。可以创建一个新线程来等待所有事件发出信号:
Thread t = new Thread(() =>
{
WaitHandle.WaitAll(handles);
MessageBox.Show("Both Threads are finished");
});
t.Start();