簡體   English   中英

如何取消正在運行的任務?

[英]How to cancel a running task?

我想取消一個正在運行的任務(當用戶按下退出鍵時)。 當我單擊“轉義”鍵Form_KeyDown運行但不取消任務時!

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token=new CancellationToken();

private async void Search_Button_ClickAsync(object sender, EventArgs e)
{
  token = tokenSource.Token;
  await (Task.Factory.StartNew(() =>
           {
             //...my program
           },
           token));

private void Form_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.Escape)
  {
    tokenSource.Cancel();
  }
}

除了您需要停止代碼在您的方法中運行之外,您一切正常。 通過將取消令牌傳遞給Task.Factory.StartNew,您不會中止任務。 讓我引用Stephen ToubStephen Toub

將令牌傳遞給StartNew會將令牌與任務相關聯。 這有兩個主要好處:1)如果令牌在任務開始執行之前已請求取消,則該任務將不會執行。 它不會立即轉換為“正在運行”,而是立即轉換為“已取消”。 如果無論如何在運行時都將其取消,則可以避免運行該任務的成本。 2)如果任務的主體也在監視取消令牌,並拋出包含該令牌的OperationCanceledException(這是ThrowIfCancellationRequested所做的事情),則當任務看到該OCE時,它將檢查OCE的令牌是否與Task的令牌匹配。 如果是這樣,則該異常被視為對合作取消的確認,並且Task轉換為Canceled狀態(而不是Faulted狀態)。

您需要手動檢查令牌是否已取消,並拋出操作已取消的異常,具體如下:

 private async void Search_Button_ClickAsync(object sender, EventArgs e)
    {
      cToken = cTokenSource.Token;
      await (Task.Factory.StartNew(() =>
               {

               for(int i=0;i<yourtaskcount;i++)
               { 
                 cToken.ThrowIfCancellationRequested();

                  //long work
               cToken));
    }
    private void Form_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Escape)
      {
        tokenSource.Cancel();
      }
    }

暫無
暫無

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

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