c# Task编程一个task抛出异常后怎么取消其他线程

从MSDN的Forum上看到别人提供的解决方案,感觉还是比较靠谱,所以就保存下来。

CancellationTokenSource cts = new CancellationTokenSource();

Task t1 = Task.Factory.StartNew(() =>

{

if (!cts.IsCancellationRequested)

{

try

{

//task body that may throw

Console.WriteLine("Task1");

}

catch

{

cts.Cancel();

throw new OperationCanceledException(cts.Token); //the task final state will be Cancelled

//the exception can be ignored if needed

}

if (cts.IsCancellationRequested)

{

//depending on the scenario

//ignore any computed result, do not persist any data, revert all changes

}

}

}, cts.Token);

Task t2 = Task.Factory.StartNew(() =>

{

if (!cts.IsCancellationRequested)

{

try

{

//task body that may throw

Console.WriteLine("Task2");

}

catch

{

cts.Cancel();

throw new OperationCanceledException(cts.Token); //the task final state will be Cancelled

}

if (cts.IsCancellationRequested)

{

//depending on the scenario

//ignore any computed result, do not persist any data, revert all changes

}

}

}, cts.Token);

2.       In case that you would like to avoid try/catch in every body you could use a Task Continuation approach like below. However with this approach, the application will pay the price of new tasks being created. At the same time the Cancellation will be delayed.

CancellationTokenSource cts = new CancellationTokenSource();

Task t1 = Task.Factory.StartNew(() =>

{

if (!cts.IsCancellationRequested)

{

//task body that may throw

Console.WriteLine("Task1");

if (cts.IsCancellationRequested)

{

//depending on the scenario

//ignore any computed result, do not persist any data, revert all changes

}

}

}, cts.Token).ContinueWith((task) =>

{

cts.Cancel();

//observe the exception

Exception ex = task.Exception;

}, TaskContinuationOptions.OnlyOnFaulted|TaskContinuationOptions.ExecuteSynchronously );

Task t2 = Task.Factory.StartNew(() =>

{

if (!cts.IsCancellationRequested)

{

//task body that may throw

Console.WriteLine("Task2");

if (cts.IsCancellationRequested)

{

//depending on the scenario

//ignore any computed result, do not persist any data, revert all changes

}

}

}, cts.Token).ContinueWith((task) =>

{

cts.Cancel();

//observe the exception

Exception ex = task.Exception;

}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

参考,转载:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/2cbe1fa7-c7dd-4e88-8773-2e3bb1665e2e/how-to-cancel-other-task-when-there-is-an-exception-in-one-of-the-task?forum=parallelextensions

时间: 2024-10-14 11:48:45

c# Task编程一个task抛出异常后怎么取消其他线程的相关文章

java并发编程实战:第七章----取消与关闭

Java没有提供任何机制来安全地终止线程(虽然Thread.stop和suspend方法提供了这样的机制,但由于存在缺陷,因此应该避免使用 中断:一种协作机制,能够使一个线程终止另一个线程的当前工作 立即停止会使共享的数据结构处于不一致的状态,需要停止时,发出中断请求,被要求中断的线程处理完他当前的任务后会自己判断是否停下来 一.任务取消 若外部代码能在某个操作正常完成之前将其置入"完成"状态,则还操作是可取消的.(用户请求取消.有时间限制的操作<并发查找结果,一个线程找到后可取

c# 写着玩的,两个Task并发,一个写队列一个读队列的异常情况

class Program { class TestEnqueue { static Queue<string> str = new Queue<string>(); public static void AddEnqueue() { for (int i = 0; i < 10; i++) { string s= i.ToString(); Console.WriteLine("Task1 now runing"); str.Enqueue(s); }

《Effective C 》资源管理:条款25--考虑写出一个不抛出异常的swap函数

条款25考虑写出一个不抛出异常的swap函数 条款25:考虑写出一个不抛出异常的swap函数 swap是STL中的标准函数,用于交换两个对象的数值.后来swap成为异常安全编程(exception-safe programming,条款29)的脊柱,也是实现自我赋值(条款11)的一个常见机制.swap的实现如下: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a=b; b=temp;

MapReduce作业的map task和reduce task调度参数

MapReduce作业可以细分为map task和reduce task,而MRAppMaster又将map task和reduce task分为四种状态: 1.pending:刚启动但尚未向resourcemanager发送资源请求: 2.scheduled:已经向resourceManager发送资源请求,但尚未分配到资源: 3.assigned:已经分配到了资源且正在运行: 4.completed:已经运行完成. map task的生命周期为:scheduled -> assigned -

.Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法

前言 .NET4.0下是没有Task.Run及Task.Delay方法的,而.NET4.5已经实现,对于还在使用.NET4.0的同学来说,如何在.NET4.0下实现这两个方法呢? 在.NET4.0下,有一个泛型类,叫TaskCompletionSource<TReuslt>,它能控制Task的行为,如给Task设置结果.设置异常.设置取消等. MSDN是这样描述的(网址): 表示未绑定到委托的 Task<TResult> 的制造者方,并通过Task属性提供对使用者方的访问. 它有以

C# Windows Schedule task之获取task下次运行时间

最近做了一个需要和Windows Schedule task相关的功能,即通过schedule,计算下次跑task的时间. 通过是用第三方的DLL来实现,从下面的网站下载: http://taskscheduler.codeplex.com/ 1. 在Schedule Task里增加一个task,命名为"testJing", trigger设置为每五天 增加一个Trigger,如下图: 2. 使用VS2012,创建一个Console Application,命名为ScheduleTas

Task.Run 和 Task.Factory.StartNew

在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至控制任务的调度行为.所有这些能力也带来了复杂性的提升,你必须知道何时应该使用何种重载方法,提供哪种调度方式等等.并且Task.Factory.StartNew这种写法也不够简洁明快,至少对它使用的主要场景不够快,一般它使用的主要场景只是将一个工作任务丢给一个后台线程执行而已. 于是,在.NET Fr

micro task 和 macro task

(js中的MacroTask) 1. Rendering never happens while the engine executes a task. Doesn’t matter if the task takes a long time. Changes to DOM are painted only after the task is complete. 当执行一个task的时候,不会渲染,不管task会执行多久,DOM的渲染会在task执行之后才进行 2. a task takes t

Task.Run vs Task.Factory.StartNew

Task.Run 和 Task.Factory.StartNew 都可以把一段要执行的代码放到ThreadPool thread中去执行.Task.Factory.StartNew是.Net 4.0中引入的,而Task.Run则是在.Net 4.5中引入,首要目的是为了简化Task.Factory.StartNew的使用.简言之, Task.Run(someAction) 与 Task.Factory.StartNew(someAction, CancellationToken.None, Ta