簡體   English   中英

如何等待多個異步操作完成

[英]How to wait on multiple asynchronous operation completion

我正在尋找一種簡單的方法來調用多個異步操作,並具有取消它們的能力:

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()

當你處理一些任務時,情況會有所不同。 首先,你需要知道取消任務的時間,其他任務會繼續嗎? 如果是,您需要為不同的任務創建不同的取消令牌並獨立處理取消。 否則,他們可以共享相同的取消令牌。 不同的要求導致不同的取消處理政策

如果您使用的是.NET 3.5或4.0,我建議使用任務並行庫(TPL)。 控制任務要容易得多,控制/取消任務的靈活性也大大提高。 檢查此鏈接任務並行如果您使用TPL並且您需要取消創建所需的所有或任何任務CancellationToken以下是如何執行此任務取消的示例。

是的,你可以在.NET 3.5中使用TPL。 以下是如何執行Reactive Extensions和Parallel Extensions的鏈接基本上您需要安裝Reactive Extensions(Rx)

Danny的代碼在邏輯上是正確的,但實際上並沒有運行。 調用WaitHandle.WaitAll()時,程序被阻止(包括兩個任務)。 可以創建一個新線程來等待所有事件發出信號:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM