ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

task取消任务

2021-08-20 09:32:13  阅读:237  来源: 互联网

标签:task1 task Console 取消 Token 任务 Task 线程


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

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

在task外部CancellationTokenSource.Cancel()。

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();
                CancellationToken Token = CTS.Token;
                Token.ThrowIfCancellationRequested();

 

 

void WorkTask(Label ThisLabel, CancellationToken Token)
        {
            try
            {

                #region 更新下载进度
                while (true)
                {
                    #region //关闭线程
                    //Token.ThrowIfCancellationRequested();//引发异常关闭线程(二选一)

                    //if (Token.IsCancellationRequested)
                    //{
                    //    //或者判断状态关闭线程(二选一)
                    //    return;
                    //}
                    #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("\nhi,我是OperationCanceledException:{0}\n", 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的代码起到效果了。

 

标签:task1,task,Console,取消,Token,任务,Task,线程
来源: https://www.cnblogs.com/cuihongyu3503319/p/15164965.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有