zoukankan      html  css  js  c++  java
  • 随笔,聊一聊任务取消

    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("主线程处理其他业务中...");
    
    }
    
    


















  • 相关阅读:
    Python 模块 itertools
    Python 字符串的encode与decode
    python 模块 hashlib(提供多个不同的加密算法)
    暴力尝试安卓gesture.key
    hdu 1300 Pearls(DP)
    hdu 1232 畅通工程(并查集)
    hdu 1856 More is better(并查集)
    hdu 1198 Farm Irrigation(并查集)
    hdu 3635 Dragon Balls(并查集)
    hdu 3038 How Many Answers Are Wrong(并查集)
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12384510.html
Copyright © 2011-2022 走看看