一、Task和多线程以及异常的捕获示例代码:
staticvoidMain(string[] args)
{//产生CancellationToken的类,该类允许使用Cancel方法终止线程//也可以使用CancellationTokenSource.CreateLinkedTokenSource创建//一组相关的Token,任意一个取消都取消CancellationTokenSource ts =newCancellationTokenSource();
CancellationToken ct=ts.Token;
Task t=null;
t=newTask(() =>{for(inti =1; i <11; i++)
{//调用Cancel方法,状态为true(表示已经取消了)if(!ts.IsCancellationRequested)
{if(i ==5)
{//该异常不会直接被主线程捕获thrownewException("数字是5,非法!");
}
}else{
Console.WriteLine("用户取消");//抛出异常,强制取消子线程ct.ThrowIfCancellationRequested();
}
Console.WriteLine(i);
Thread.Sleep(500);
}
}, ct);
t.Start();//注册Cancel之后的引发的事件,注意Exception也可以在这里捕获t.ContinueWith((task) =>{//只有调用Cancel方法才会被设置为TrueConsole.WriteLine(t.IsCanceled);//无论何种情况,只要完成了就是TrueConsole.WriteLine(t.IsCompleted);//只要有异常,为True(哪怕是ThrowIfCancellationRequested异常)Console.WriteLine(t.IsFaulted);//捕获各种各样的异常foreach(varitemintask.Exception.InnerExceptions)
{
Console.WriteLine(item.Message);
}
});
Console.ReadLine();//取消任务ts.Cancel();
Thread.Sleep(Timeout.Infinite);
}
结论:
1、无论任何异常都会终止子线程。
2、异常发生之后,只有在Task的Wait/WaitAll/WaitAny/Result或者Continue方法才可以捕获异常,主线程不可能,因为是子线程中的异常。
二、Task的任务先后顺序(允许嵌套任务),同时允许把线程挂接到主线程上执行返回结果(避免以前Thread和WinForm控件交互时候发生的“不是由本线程创建的控件异常……”问题):
staticvoidMain(string[] args)
{
CancellationTokenSource cts=newCancellationTokenSource();
CancellationToken ct=cts.Token;
Task t=newTask(() =>{
Console.WriteLine("主任务开始……,包含3个子任务:");
Task.Factory.StartNew(()=>{
Thread.Sleep(2000);
Console.WriteLine("任务一");
},//挂接到主线程,这样主线程会自动等待子线程完成后完成TaskCreationOptions.AttachedToParent );
Task.Factory.StartNew(()=>{
Thread.Sleep(500);
Console.WriteLine("任务二");
}, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(()=>{
Thread.Sleep(1000);
Console.WriteLine("任务三");
},
TaskCreationOptions.AttachedToParent);
}, ct);
t.ContinueWith((Task)=>{
Console.WriteLine("子任务都完成,主任务结束。");//指定上下文的同步块,防止跨线程访问控件的问题(控制台程序不能使用,WinForm啥可以)},TaskScheduler.FromCurrentSynchronizationContext());
t.Start();
Thread.Sleep(Timeout.Infinite);
}
相比较原来的Wait而言,不会卡死子线程,而且又可以多任务运行。
欲想知道更多关于线程操作的东西,可以参考:
MSDN,并行处理系列篇:http://msdn.microsoft.com/zh-cn/library/vstudio/3e8s7xdd(v=vs.110).aspx