用Task代替Thread时,Abort和IsBackground两个属性的处理。。

phommy 2014-06-13 05:49:30
在Task里没有找到能代替这两个属性的方法。。。

场景的话,比如:

Abort:我在子线程或Task里执行一个同步操作(比如Semaphore.WaitOne或者等一个sql执行完毕),主进程不想等了,就可以随时Abort掉。但Task中并不存在判断CancellationTokenSource的时机

IsBackground:这个场景就简单了,主线程退出时,自动终止没完成的Task,这个可以直接通过一个属性做到吗?如果不能,常规处理方式是什么呢?
...全文
1207 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljz_08 2015-04-07
  • 打赏
  • 举报
回复
楼主我也遇到一样的需求。不知道你现在解决了没有?分享一下
暈哥 2014-06-16
  • 打赏
  • 举报
回复
“线程不是说停就停” 说的就是你这种情况,即使是Abort也会等sql执行返回才会停止; 另外Task也不太适合这种情况,一般用来执行“短小精悍”的任务; 不管是任何形式的线程都不该由其他线程来停止,而是自身控制退出,对外提供接口(CancellationToken或bool标识) 如果非得中途取消sql执行可以试试前台线程+事物。
phommy 2014-06-16
  • 打赏
  • 举报
回复
引用 1 楼 lineages 的回复:
请忘记Abort这个方法,你说的“不存在判断CancellationTokenSource的时机”是在纠结什么,至于你说的“可以随时Abort掉”那是你想当然,线程并不是说停就停的,我们不要试图去控制线程,应该去控制交给线程处理的任务。 Task的出现就是为了解决线程池太鸡肋的问题,生来就是后台线程。
谢谢~ 第2个问题你这样说我就懂了。 第1个问题,比如说sql server的查询分析器上有个“停止”按钮,在执行用时很长的sql时可以随时按这个按钮中止掉。如果用 Thread实现,就是在子线程里执行 ExecuteScalar,用户在界面进程点“停止”时杀掉子进程就行了;换用Task要怎么实现呢?
phommy 2014-06-16
  • 打赏
  • 举报
回复
引用 4 楼 yun738243875 的回复:

			CancellationTokenSource cts = new CancellationTokenSource();
			Task<int> t = new Task<int>(() => Sum(cts.Token, 1000), cts.Token);
			t.Start();
			Console.WriteLine("Press <Enter> to cancel the operation");
			Console.Read();
			cts.Cancel();
			try {
				t.Wait();
			} catch (AggregateException ex) {
				ex.Handle(p => p is OperationCanceledException);
				Console.WriteLine("Sum was Canceled.");
			}
			Thread.Sleep(10000);

static int Sum(CancellationToken token, int n) {
			int sum = 0;
			for (; n > 0; n--) {
				token.ThrowIfCancellationRequested();
				checked {
					sum += n;
				}
				Console.Write("{0} ", n);
				Thread.Sleep(1000);
			}
			return sum;
		}
楼主懂了么?主要利用CancellationToken在任务中如果调用它的Cancel方法会抛出AggregateException异常,主线程只要捕获这个异常并且处理他,就说明任务被取消了。
你的例子我懂了,但我需要更“一般”的写法。。。在你的例子中,最耗时的部分“恰好”是你自己的一个循环,所以你才可以在每次循环中都判断一次任务是否被取消了 (利用token.ThrowIfCancellationRequested) 。 但如果最耗时的部分不是我的代码怎么办呢,比如我就是调用了.net执行sql语句的操作,而这个操作相当耗时、我也没有办法要求他去隔段时间调用一下 token.ThrowIfCancellationRequested 。。。
yun738243875 2014-06-16
  • 打赏
  • 举报
回复

			CancellationTokenSource cts = new CancellationTokenSource();
			Task<int> t = new Task<int>(() => Sum(cts.Token, 1000), cts.Token);
			t.Start();
			Console.WriteLine("Press <Enter> to cancel the operation");
			Console.Read();
			cts.Cancel();
			try {
				t.Wait();
			} catch (AggregateException ex) {
				ex.Handle(p => p is OperationCanceledException);
				Console.WriteLine("Sum was Canceled.");
			}
			Thread.Sleep(10000);

static int Sum(CancellationToken token, int n) {
			int sum = 0;
			for (; n > 0; n--) {
				token.ThrowIfCancellationRequested();
				checked {
					sum += n;
				}
				Console.Write("{0} ", n);
				Thread.Sleep(1000);
			}
			return sum;
		}
楼主懂了么?主要利用CancellationToken在任务中如果调用它的Cancel方法会抛出AggregateException异常,主线程只要捕获这个异常并且处理他,就说明任务被取消了。
暈哥 2014-06-13
  • 打赏
  • 举报
回复
请忘记Abort这个方法,你说的“不存在判断CancellationTokenSource的时机”是在纠结什么,至于你说的“可以随时Abort掉”那是你想当然,线程并不是说停就停的,我们不要试图去控制线程,应该去控制交给线程处理的任务。 Task的出现就是为了解决线程池太鸡肋的问题,生来就是后台线程。
内容概要:本文详细介绍了利用Simulink进行变压器开路试验的电路连接配置与仿真实现方法,重点在于通过仿真手段还原实际电力系统中变压器在空载条件下的电气特性,从而深入理解其工作原理与性能表现。文章作为电力系统仿真系列研究的一部分,系统阐述了从电路模型搭建、参数设定、仿真运行到结果分析的完整流程,突出展示了MATLAB/Simulink在电力设备建模与教学科研中的强大功能与应用价值。; 适合人群:具备电力系统基础知识,熟悉MATLAB/Simulink仿真环境,从事电气工程、自动化及相关领域的研发人员,以及高年级本科生和研究生。; 使用场景及目标:①掌握变压器开路试验的基本原理与Simulink仿真建模的具体步骤;②通过仿真实验深入理解空载电流、铁芯损耗及励磁特性等关键参数的物理意义;③为后续开展变压器短路试验、暂态过程分析以及其他电力设备的仿真研究奠定理论与实践基础。; 阅读建议:建议结合Simulink软件动手实践,逐步构建并调试电路模型,重点关注各元件参数的设置方法与测量模块的应用技巧,同推荐参考文中提及的其他相关仿真案例进行拓展学习,以全面提升对电力系统仿真实践的整体认知与操作能力。

111,132

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧