簡體   English   中英

ThrowIfCancellationRequested似乎沒有拋出任何異常

[英]ThrowIfCancellationRequested doesn't seem to throw any exceptions

我有以下代碼:

CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;

Task.Factory.StartNew(() =>
{
     if (Console.ReadKey().KeyChar == 'c')
         cts.Cancel();
     Console.WriteLine("press any key to exit");
});

 Parallel.ForEach(list, po, (algo) =>
 {
      algo.Compute(); // this compute lasts 1 minute  
      Console.WriteLine("this job is finished");       
      po.CancellationToken.ThrowIfCancellationRequested();
 });

list包含很少的元素。 當我按'c'時,所有的Compute方法都已經啟動了。

當我按'c'時,不會拋出任何異常。 每個Compute方法都會繼續執行,直到正常結束。

當我按'c'時,我想停止/殺死所有剩余的Compute方法。

取消不是那樣的。 這不像調用Thread.Abort()來立即終止線程。

對於代碼中序列中的每個元素:

  1. 調用Compute()方法
  2. 等到完成
  3. 寫入控制台關於完成
  4. 檢查是否請求取消,如果是,則拋出OperationCanceledException

要取消某些任務,您需要將CancellationToken傳遞給被調用的方法。
也許,值得將長時間運行的計算作為一個循環進行組織,並檢查是否在每一步都要求取消,以便盡快停止。

例如,在Compute()方法中,您可以執行以下檢查:

private void Compute(CancellationToken ct)
{
    while (true)
    {
       ComputeNextStep();
       ct.ThrowIfCancellationRequested();
    }
}

使用po.CancellationToken.IsCancellationRequested觀察取消並使用ParallelLoopState.Stop來停止Parallel.ForEach

void Compute(CancellationToken token, ParallelLoopState loopState)
{
    bool more = true;
    while (more)
    {
        if (token.IsCancellationRequested)
        {
            // stop Parallel.ForEach ASAP
            loopState.Stop();
            return;
        }
        // do the calc step
    }
}

// ... 

CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;

Task.Factory.StartNew(() =>
{
    if (Console.ReadKey().KeyChar == 'c')
        cts.Cancel();
    Console.WriteLine("press any key to exit");
});

Parallel.ForEach(list, po, (algo, loopState) =>
{
    algo.Compute(po.CancellationToken, loopState); // this compute lasts 1 minute  
    Console.WriteLine("this job is finished");
});
// observe the cancellation again and throw after Parallel.ForEach
po.CancellationToken.ThrowIfCancellationRequested();

暫無
暫無

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

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