多线程编程中要注意对线程异常的处理。首先写个例子。
一个线程用于显示信息(Show Messages)。主线程用于做其他工作(Do Works)。
using (Task taskShowMessages = new Task(ShowMessages)) { try { taskShowMessages.Start(); DoWorks(); } catch (DoWorkException ex) { Console.WriteLine("Error:{0}", ex.Message); } catch(Exception ex) { Console.WriteLine("Error:{0}", ex.Message); } }
public static void ShowMessages() { int i = 0; while (true) { Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++); Thread.Sleep(1000); if ( i == 3) { throw new ShowMessageException(string.Format("User defined error occured during showing message_{0}!", i)); //throw new Exception(string.Format("Unhandled exception occured during showing message_{0}!", i)); } } } public static void DoWorks() { int i = 0; while (true) { Console.WriteLine("{0} - DoWork_{1}", DateTime.Now.ToString(), i++); Thread.Sleep(2000); if (i == 4) { throw new DoWorkException(string.Format("User defined error occured during doing work_{0}!", i)); //throw new Exception(string.Format("Unhandled exception occured during doing work{0}!", i)); } } } public class ShowMessageException : Exception { public ShowMessageException(String message) : base(message) { } } public class DoWorkException : Exception { public DoWorkException(String message) : base(message) { } }
输出:
12/27/2015 10:08:03 PM - DoWork_0 12/27/2015 10:08:03 PM - Message_0 12/27/2015 10:08:04 PM - Message_1 12/27/2015 10:08:05 PM - DoWork_1 12/27/2015 10:08:05 PM - Message_2 12/27/2015 10:08:07 PM - DoWork_2 12/27/2015 10:08:09 PM - DoWork_3 Error:User defined error occured during doing work_4!
可以看出来,Show Message 3 时发生一个异常,但是本程序无视它并继续DoWorks。知道DoWorks发生异常抛出。
在VS的debug环境下可以看到这个异常的发生:
A first chance exception of type ‘ConsoleApplication2.Program.ShowMessageException‘ occurred in ConsoleApplication2.exe A first chance exception of type ‘ConsoleApplication2.Program.DoWorkException‘ occurred in ConsoleApplication2.exe
如果想正确的处理ShowMessage线程的异常,必须对其 Wait()方法进行处理。
using (Task taskShowMessages = new Task(ShowMessages)) { try { taskShowMessages.Start(); DoWorks(); } catch (DoWorkException ex) { Console.WriteLine("Error is handled:{0}", ex.Message); } finally { try { taskShowMessages.Wait(); } catch(AggregateException ae) { ae.Handle((x) => { if (x is ShowMessageException) { Console.WriteLine("Error is handled:{0}", x.Message); return true; } else { return false; } }); } } }
输出:
12/27/2015 10:16:37 PM - DoWork_0 12/27/2015 10:16:37 PM - Message_0 12/27/2015 10:16:38 PM - Message_1 12/27/2015 10:16:39 PM - DoWork_1 12/27/2015 10:16:39 PM - Message_2 12/27/2015 10:16:41 PM - DoWork_2 12/27/2015 10:16:43 PM - DoWork_3 Error is handled:User defined error occured during doing work_4! Error is handled:User defined error occured during showing message_3!
那么现在如果其中一个线程出现异常的话,我们就希望抛出异常,结束程序,怎么做?
答案就是使用:
CancellationTokenSource
static CancellationTokenSource cancellationtoken = new CancellationTokenSource(); static void Main(string[] args) { using (Task taskShowMessages = new Task(ShowMessages, cancellationtoken.Token)) { try { taskShowMessages.Start(); DoWorks(); } catch (DoWorkException ex) { Console.WriteLine("Error is handled:{0}", ex.Message); } finally { cancellationtoken.Cancel(); try { taskShowMessages.Wait(); } catch (AggregateException ae) { ae.Handle((x) => { if (x is ShowMessageException) { Console.WriteLine("Error is handled:{0}", x.Message); return true; } else { return false; } }); } } } } public static void ShowMessages() { int i = 0; while (!cancellationtoken.IsCancellationRequested) { Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++); Thread.Sleep(1000); if ( i == 3) { //throw new ShowMessageException(string.Format("User defined error occured during showing message_{0}!", i)); //throw new Exception(string.Format("Unhandled exception occured during showing message_{0}!", i)); //break; } } }
输出:
12/27/2015 10:40:56 PM - DoWork_0 12/27/2015 10:40:56 PM - Message_0 12/27/2015 10:40:57 PM - Message_1 12/27/2015 10:40:58 PM - DoWork_1 12/27/2015 10:40:58 PM - Message_2 12/27/2015 10:40:59 PM - Message_3 12/27/2015 10:41:00 PM - DoWork_2 12/27/2015 10:41:00 PM - Message_4 12/27/2015 10:41:01 PM - Message_5 12/27/2015 10:41:02 PM - DoWork_3 12/27/2015 10:41:02 PM - Message_6 12/27/2015 10:41:03 PM - Message_7 Error is handled:User defined error occured during doing work_4!
参考:
https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/dd537614(v=vs.110).aspx
(C#) Tasks 中的异常处理(Exception Handling.)
原文:http://www.cnblogs.com/fdyang/p/5081058.html