task好像没有在线程外取消任务的操作,没有类似于Thread.Abort();这样停止线程的操作,当然,也可以在task生成时,把task所属的线程记录下来,然后用Thread.Abort()停止,因为task本身也是附属与这个线程的,线程停了,task肯定也停了,不过这样那还不如直接用Thread做多线程异步处理了,何必废二遍事。
在task内部有两种方式关闭线程,一种是引发异常,一种是用用Token.IsCancellationRequested自己判断状态关闭。
在task外部CancellationTokenSource.Cancel()。//通知关闭Task
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); |
1 2 3 | //关闭线程 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("\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的代码起到效果了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2020-08-20 SQL Server 2019下载及安装教程
2020-08-20 SQL Server 密钥(含2019)
2018-08-20 solr 忽略大小写
2012-08-20 【问题总结】WCF寄宿与IIS里时遇到的问题
2012-08-20 WPF选择.NET Framework 4 Client Profile提示找不到名字空间
2011-08-20 ORM最简单的设计
2010-08-20 给目前自己开发的分布式系统做个定义