如何等待多个异步操作完成

时间:2011-08-02 02:54:03

标签: c# .net

我正在寻找一种简单的方法来调用多个异步操作并取消它们:

var cancelTask = new ManualResetEvent(false);
IAsyncResult ar = StartAsyncBatch(cancelTask);
int resp = WaitHandler.WaitAny({ar.AsyncWaitHandle, cancelTask});

我如何构建StartAsyncBatch?它应该是派生类

class StartAsyncBatch : IAsyncResult

3 个答案:

答案 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();