• 随笔,聊一聊任务取消


    1,在写根plc通讯的时候,有时候需要取消任务.


    一般就是需要建立 一个canceltokensource对象.

      然后将其 token参数传递给 异步的过程.(注意,过程函数必须要实现token的IscancelRequest的功能)

    2,有以下几个地方

    • m_cts.Cancel():用来调用Cancel(),并且将IsCancellationRequested=true;
    • m_cts.CancleAfter();这个函数用来延迟一定时间后调用取消指令.
    • m_cts.register,事件,用来回调当事件取消后触发的事件.

    有以下几个方法实现取消等待:

    Task t1 = plc.OpenAsync();
    
                   //---
                   Task t2 = Task.Run(() =>//一种将没有取消功能的异步函数增加取消功能.
                    {
    
                       do
                        {
    
    
                            if (token.IsCancellationRequested)
                            {
                                throw new Exception("通讯超时");
    
                            }
                            if (t1.IsFaulted) throw t1.Exception;
    
                       } while (!t1.IsCompleted);
    
                   }, token
                );
                    //---
                   await t2;//关键功能!
    

    可以把if那段改成 token.throwifcancellexception:就是如果cancel了,就抛出错误.可能更号店.

    利用循环,在循环那里,进行捕捉任务1的异常.

    方法2:使用非任务的方式,比较简单粗暴.

                   Task t1= plc.OpenAsync();
                    while (!t1.IsCompleted) {  token.ThrowIfCancellationRequested(); }

    3,使用 t.wait(token)可以人为取消等待.


    4,当在其他线程访问控件时候.https://www.cnblogs.com/songxingzhu/p/3677307.html


    void  m_comm_MessageEvent( string  msg)
        {
         if (txtMessage.InvokeRequired)
         {
         InvokeCallbackmsgCallback  =   new  InvokeCallback(m_comm_MessageEvent);
         txtMessage.Invoke(msgCallback,  new   object []  { msg } );
        }
         else
         {
         txtMessage.Text  =  msg;
        }
       }


    意思是当异步线程调用的时候,需要使用invoke函数,来进行封装调用.(解决了异步执行调用的问题.).

    一个定时取消任务的方式:

    private System.Threading.Timer t;
    
    private void cancelJob(object obj)
    {
        Thread tempT = (Thread)obj;
        if(tempT.IsAlive)
        {
            if (listBox1.InvokeRequired)
            {
                listBox1.Invoke(new Action(() => listBox1.Items.Add("作业将被取消...")));
            }
            t.Dispose();
    
            //做好强行中断线程前的准备工作,如回滚业务逻辑等
            tempT.Abort();
    
        }
    }
    
    private void bigJob()
    {
        if(listBox1.InvokeRequired)
        {
            listBox1.Invoke(new Action(() => listBox1.Items.Add("开始处理大型作业...")));
        }
    
        Thread.Sleep(5000); //模拟耗时操作
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        Thread asyncJob = new Thread(bigJob);
        asyncJob.Start();
    
        TimerCallback tCallBack = new TimerCallback(cancelJob);
        t = new System.Threading.Timer(tCallBack, asyncJob, 3000, 0); //3秒后启动回调函数tCallBack
    
        listBox1.Items.Add("主线程处理其他业务中...");
    
    }
    
    


















  • 相关阅读:
    Android CTS(frome google)
    Android CTS
    【Linux】- 修改系统时间与时区
    【Linux】- CentOS查看IP
    【Linux】- Ubutnu UFW防火墙的简单设置
    【Linux】- Ubuntu安装nginx
    【Linux】- apt-get命令
    【Linux】- Ubuntu搭建FTP服务器
    【Linux】- Ubuntu 配置mysql远程访问
    【Linux】- Ubuntu安装redis,并开启远程访问
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12384510.html
Copyright © 2020-2023  润新知