在等待最近的方法C#中取消任务

时间:2018-03-13 13:06:16

标签: c# task

我想以干净简单的方式取消Task.run,这是我的代码:

bool NTAG_isHere = false;

// CODE (...)

private async Task Dump_NTAG(object sender, EventArgs eventArgs)
{
    // while NTAG PRESENT DUMP START:
    await Task.Run(() => {while (NTAG_isHere()) { } });

    // CODE (...)

    // If NTAG NOT PRESENT or not detected stop the dump and kill thread:
    if(!NTAG_isHere)
    {
      // kill the thread
    }

{

谢谢,

编辑4,我的完整方法:

    private void Dump_NTAG(object sender, EventArgs eventArgs)
    {
        try
        {
            richTextBox_debug.Invoke(new UpdateTextCallback(CleanText), new object[] {string.Empty});


            WriteLine(NTAG_isHere());

            if (!NTAG_isHere())
            {
                Task.Factory.StartNew(() =>
                {
                    richTextBox_debug.Invoke(new UpdateTextCallback(CleanText), new object[] { string.Empty });
                    byte[] dump = new byte[540];
                    int i;
                    richTextBox_debug.Invoke(new UpdateTextCallback(UpdateText), new object[] { "START" + Environment.NewLine + Environment.NewLine });
                    for (i = 0; i < 135; i++)
                    {
                        string Result = arduino.SendCommand("/READ " + i);
                        string[] SplitResult = Result.Split('/', ' ');

                        if (SplitResult.Length > 1)
                        {
                            if (Result.Split('/', ' ')[1] == "ERROR")
                                richTextBox_debug.Invoke(new UpdateTextCallback(UpdateText), new object[] { string.Format("NFC_Error" + Result.Substring(1) + Environment.NewLine) });

                            else
                                richTextBox_debug.Invoke(new UpdateTextCallback(UpdateText), new object[] { string.Format("NFC_Unknown_Response" + Result + Environment.NewLine) });

                            i = 135;
                        }
                        else
                        {
                            string page = "Page";
                            richTextBox_debug.Invoke(new UpdateTextCallback(UpdateText), new object[] { string.Format(page + " {0} : {1}", i, Result) + Environment.NewLine });
                        }
                    }

                    if (i == 135) { richTextBox_debug.Invoke(new UpdateTextCallback(UpdateText), new object[] { "Dump success !" + Environment.NewLine + Environment.NewLine });  }

                    arduino.SendCommand("/NTAG_HALT");
                    arduino.Close();
                });
            }
            else
            {
                MessageBox.Show("ERROR !!");
            }
        }
        catch (Exception e)
        {

            WriteLine(e.Message);
        }
    }

我担心的是我不能再转储了,这个新代码的布尔值仍然是错误的,但我的方法NTAG_isHere()返回了良好的值,因此不存在问题。而且我永远不会传入MessageBox.Show(“ERROR !!”);在播放器上有或没有ntag

1 个答案:

答案 0 :(得分:0)

现在查看你的代码,你可以简单地做到这一点,没有必要取消的东西,只需检查方法returns true而不是运行任务别的

   private void Read_amiibo(object sender, EventArgs eventArgs)
    {
         bool ishere = NTAG_isHere();
        //store reference of local thread 
        if(ishere)
        {
            Task.Factory.StartNew(() =>
            {
              //do operation
            }
        }
        else {
         //exit
        }
    }

添加她的一点 e:如果你使用async / await你的调用会在等待遇到时返回并且下面的代码将不会被执行

以下解决方案适用于没有async / await

的情况

CancellationTokenSource用于将为您完成的任务,您可以将CancellationToken作为参数传递给run方法并监视它以取消。

这是微软团队提供的更清洁的方式。

 var tokenSource = new CancellationTokenSource();
 var token = tokenSource.Token;
 var t = Task.Run( () => { 
              //perform task 
             if (token.IsCancellationRequested) 
                    token.ThrowIfCancellationRequested();
               }    , token);

  if(!NTAG_isHere)
   {
     // kill the thread
     tokenSource.Cancel();
  }

其他方式不太推荐,

        //store reference of local thread 
        Thread threadToCancel = null;
        Task.Factory.StartNew(() =>
        {
            //Capture the thread
            threadToCancel = Thread.CurrentThread;
        }

        //you can put timer also , means check value after some time to avoid while loop 
         while(true) {
           if(NTAG_isHere){
             threadToCancel.Abort();
          } 
        }

在这里讨论了这种方法:Abort/Cancel Task

参考检查:Task.Run Method (Action, CancellationToken)