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

C# 如何等待多个异步操作完成,c#,.net,C#,.net,我正在寻找一种调用多个异步操作并能够取消它们的简单方法: var cancelTask = new ManualResetEvent(false); IAsyncResult ar = StartAsyncBatch(cancelTask); int resp = WaitHandler.WaitAny({ar.AsyncWaitHandle, cancelTask}); 我如何构建StartAsyncBatch?它应该是派生类吗 class StartAsyncBatch : IAsyncR

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

var cancelTask = new ManualResetEvent(false);
IAsyncResult ar = StartAsyncBatch(cancelTask);
int resp = WaitHandler.WaitAny({ar.AsyncWaitHandle, cancelTask});
我如何构建StartAsyncBatch?它应该是派生类吗

class StartAsyncBatch : IAsyncResult

简单的回答是,您可以通过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()
var tokenSource=new CancellationTokenSource();
var task=task.Factory.StartNew(()=>
{
对于(int i=0;i<10;i++)
{
if(tokenSource.IsCancellationRequested)
{
//你知道任务被取消了
//做点什么来停止这项任务
//或者您可以使用tokenSource.Token.ThrowIfCancellationRequested()
//控制流量
}
其他的
{
//进行第一步工作
}
}
},tokenSource.Token);
尝试
{
task.Wait(tokenSource.Token);
}
捕获(操作取消异常取消)
{ 
//滚回去什么的
}
//某个地方,例如,您调用tokenSource.cancel()的取消按钮单击事件

当你处理一些任务时,事情会有点不同。首先,您需要知道取消任务时,其他任务是否会继续?如果是,您需要为不同的任务创建不同的取消令牌,并独立处理取消。否则,它们可以共享相同的取消令牌。不同的需求导致不同的取消处理策略。

如果您使用的是.NET 3.5或4.0,我建议您使用任务并行库(TPL)。控制任务更容易,控制/取消任务也更灵活。如果您使用TPL并且需要取消创建CancellationToken所需的所有或任何任务,请选中此链接。下面是一个如何执行此操作的示例


是的,您可以在.NET3.5中使用TPL。下面是如何做到这一点的链接,基本上你需要安装反应式扩展(Rx)

Danny的代码在逻辑上是正确的,但实际上没有运行。调用WaitHandle.WaitAll()时,程序被阻止(包括两个任务)。可以创建一个新线程来等待所有事件发出信号:

Thread t = new Thread(() =>
{
      WaitHandle.WaitAll(handles);
      MessageBox.Show("Both Threads are finished");
});
t.Start();