zoukankan      html  css  js  c++  java
  • task取消任务

    task好像没有在线程外取消任务的操作,没有类似于Thread.Abort();这样停止线程的操作,当然,也可以在task生成时,把task所属的线程记录下来,然后用Thread.Abort()停止,因为task本身也是附属与这个线程的,线程停了,task肯定也停了,不过这样那还不如直接用Thread做多线程异步处理了,何必废二遍事。

    在task内部有两种方式关闭线程,一种是引发异常,一种是用用Token.IsCancellationRequested自己判断状态关闭。

    在task外部CancellationTokenSource.Cancel()。//通知关闭Task

    Label Label1 = sp.FindName("Label1") as Label;
    
    
                CancellationTokenSource CTS = new CancellationTokenSource();
                CancellationToken Token = CTS.Token;
    
                //1.new方式实例化一个Task,需要通过Start方法启动
                Task task = new Task(() =>
                {
                    //置为后台线程(Task默认就是为后台线程)
                    //Thread.CurrentThread.IsBackground = true;//后台线程在应用程序退出时都会自动结束(主窗体关闭后台线程自动结束)
                    WorkTask(Label1, Token);
                }, Token);
                task.Start();
    
                    //关闭线程
                    CancellationTokenSource CTS = CT.CTS;
                    CTS.Cancel();//通知关闭Task
    
            void WorkTask(Label ThisLabel, CancellationToken Token)
            {
                try
                {
    
                    #region 更新下载进度
                    while (true)
                    {
                        #region //关闭线程
                        Token.ThrowIfCancellationRequested();//引发异常关闭线程(二选一)
    
                        //if (Token.IsCancellationRequested)
                        //{
                        //    //或者判断状态关闭线程(二选一)
                        //    return;
                        //}
    
                        //if (Token.IsCancellationRequested)
                        //{
                        //    System.Threading.Thread.CurrentThread.Abort();//或者使用当前线程Abort()也可以
                        //}
                        #endregion
    
                        // 更新下载进度
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            ThisLabel.Content = "下载中...." + DateTime.Now.ToString("HH:mm:ss") + "/" + DateTime.Now.ToString("HH:mm:ss");
    
                        }));
                        // 后台线程停顿1秒    
                        Thread.Sleep(1000);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    LogHelper.AddLog(AbnormalType.info, "YiBuTest2,Thread1异常:-->" + ex.Message);
                }
    
            }

    取消任务

       我们知道task是并行计算的,比如说主线程在某个时刻由于某种原因要取消某个task的执行,我们能做到吗? 当然我们可以做到。

    在4.0中给我们提供一个“取消标记”叫做CancellationTokenSource.Token,在创建task的时候传入此参数,就可以将主线程和任务相

    关联,然后在任务中设置“取消信号“叫做ThrowIfCancellationRequested来等待主线程使用Cancel来通知,一旦cancel被调用。task将会

    抛出OperationCanceledException来中断此任务的执行,最后将当前task的Status的IsCanceled属性设为true。看起来是不是很抽象,

    没关系,上代码说话。

    复制代码
    复制代码
     1 using System;
    2 using System.Threading;
    3 using System.Threading.Tasks;
    4 using System.Diagnostics;
    5 class Program
    6 {
    7 static void Main(string[] args)
    8 {
    9 var cts = new CancellationTokenSource();
    10 var ct = cts.Token;
    11
    12 Task task1 = new Task(() => { Run1(ct); }, ct);
    13
    14 Task task2 = new Task(Run2);
    15
    16 try
    17 {
    18 task1.Start();
    19 task2.Start();
    20
    21 Thread.Sleep(1000);
    22
    23 cts.Cancel();
    24
    25 Task.WaitAll(task1, task2);
    26 }
    27 catch (AggregateException ex)
    28 {
    29 foreach (var e in ex.InnerExceptions)
    30 {
    31 Console.WriteLine(" hi,我是OperationCanceledException:{0} ", e.Message);
    32 }
    33
    34 //task1是否取消
    35 Console.WriteLine("task1是不是被取消了? {0}", task1.IsCanceled);
    36 Console.WriteLine("task2是不是被取消了? {0}", task2.IsCanceled);
    37 }
    38
    39 Console.Read();
    40 }
    41
    42 static void Run1(CancellationToken ct)
    43 {
    44 ct.ThrowIfCancellationRequested();
    45
    46 Console.WriteLine("我是任务1");
    47
    48 Thread.Sleep(2000);
    49
    50 ct.ThrowIfCancellationRequested();
    51
    52 Console.WriteLine("我是任务1的第二部分信息");
    53 }
    54
    55 static void Run2()
    56 {
    57 Console.WriteLine("我是任务2");
    58 }
    59 }
    复制代码
    复制代码

    从图中可以看出

    ①:Run1中的Console.WriteLine("我是任务1的第二部分信息"); 没有被执行。

    ②:Console.WriteLine("task1是不是被取消了? {0}", task1.IsCanceled); 状态为True。

    也就告诉我们Run1中途被主线程中断执行,我们coding的代码起到效果了。

  • 相关阅读:
    【转载】C/C++中extern关键字详解
    【转载】extern "C"的用法解析(原博主就是抄百度百科的,不如另外一篇好)
    lua Date和Time
    MySQL-Linux安装
    Hive-0.13安装
    MR案例:单表关联查询
    MR案例:小文件处理方案
    MR案例:链式ChainMapper
    MR案例:定制Partitioner
    MR案例:多文件输出MultipleOutputs
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/15164965.html
Copyright © 2011-2022 走看看