首页 > 解决方案 > C#为创建的每个任务使用取消令牌

问题描述

我有一个任务方法,可以在我的 MainWindow 中生成温度曲线,但是当用户将很多(生产的物品)的数据输入烤箱并每 30 秒记录一次温度时,它会以另一种形式调用。

public static async Task genLotProfile(string lotno,string filename, string datch,CancellationToken token)

try
{
       //get temperature and do other stuff
       Tprofile temp = getLogData(datch); 
       
       //task delay
       while (!token.IsCancellationRequested)
      {
          //Task delay
          await Task.Delay(30000, token);
      }
}
catch (OperationCanceledException e)
{

}

我的想法是每次输入很多内容时都在输入表单中的输入按钮功能上调用它。

private void EnterBtn_Click(object sender, RoutedEventArgs e)
{
   //do other stuff

   //Call generate temp profile
    string filename = MainWindow.getTempProfileName(MainWindow.datachannel, lotnoTBX.Text);
                
    CancellationToken token = source.Token;
                
    MainWindow.genLotProfile(lotnoTBX.Text, filename, MainWindow.datachannel, token);
}

我还有一个单独的取消课程

    class Cancel
    {
        CancellationTokenSource _source;

        public Cancel(CancellationTokenSource source)
        {
            _source = source;
        }

        public void cancelTask()
        {
            _source.Cancel();
        }
    }

问题是我将在我的条件下运行多个任务,并且当用户从烤箱中取出很多东西时,我想在另一个输出表单上使用 Cancel 类杀死特定任务,如果我这样做,取消令牌会杀死我正在运行的所有任务下列的

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Cancel c = new Cancel(source); 
c.cancelTask();

标签: c#wpftask

解决方案


您需要为每个任务创建新的 CancellationTokenSource:

private async void EnterBtn_Click(object sender, RoutedEventArgs e)
{
   //do other stuff

   //Call generate temp profile
    string filename = MainWindow.getTempProfileName(MainWindow.datachannel, lotnoTBX.Text);

    CancellationTokenSource source = new CancellationTokenSource();                
    CancellationToken token = source.Token;
                
    await MainWindow.genLotProfile(lotnoTBX.Text, filename, MainWindow.datachannel, token);
}

取消特定任务时,您只需调用正确的令牌实例 cancel()。


推荐阅读