(C#) Tasks 中的异常处理(Exception Handling.)
2015-12-27 22:43
656 查看
多线程编程中要注意对线程异常的处理。首先写个例子。
一个线程用于显示信息(Show Messages)。主线程用于做其他工作(Do Works)。
输出:
可以看出来,Show Message 3 时发生一个异常,但是本程序无视它并继续DoWorks。知道DoWorks发生异常抛出。
在VS的debug环境下可以看到这个异常的发生:
如果想正确的处理ShowMessage线程的异常,必须对其 Wait()方法进行处理。
输出:
那么现在如果其中一个线程出现异常的话,我们就希望抛出异常,结束程序,怎么做?
答案就是使用:
CancellationTokenSource
输出:
参考:
https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/dd537614(v=vs.110).aspx
一个线程用于显示信息(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#webBrowser 获取标签值
- C#创建图片验证码
- C#中的is和as操作符
- C#语言基础----值类型
- 【NCRE】C# WindowForm实现屏幕最顶端拖动
- C#学习一之基础认识
- c#通过webbrowser获取网页中的超链接地址
- C#入门之简单计算器的实现。
- 《c#之全局观》
- C# 字段(Field)、属性(Property)、特性(Attribute)
- C#中字符串的处理
- C#委托
- C#多态
- C# webBrowser控件使用心得
- C#WebBrowser控件使用教程与技巧收集--苏飞收集
- C#视频总结
- C#-字符数组(笔记)
- 【C#学习】——接口例子
- C#面向对象设计模式纵横谈——6.Prototype 原型模式(创建型模式)
- C#学习笔记007-字符串练习