多线程编程中要注意对线程异常的处理。首先写个例子。

一个线程用于显示信息(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 = ;
while (true)
{
Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++);
Thread.Sleep(); 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 = ;
while (true)
{
Console.WriteLine("{0} - DoWork_{1}", DateTime.Now.ToString(), i++);
Thread.Sleep(); if (i == )
{
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)
{
}
}

输出:

// :: PM - DoWork_0
// :: PM - Message_0
// :: PM - Message_1
// :: PM - DoWork_1
// :: PM - Message_2
// :: PM - DoWork_2
// :: 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;
}
});
}
}
}

输出:

// :: PM - DoWork_0
// :: PM - Message_0
// :: PM - Message_1
// :: PM - DoWork_1
// :: PM - Message_2
// :: PM - DoWork_2
// :: 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 = ;
while (!cancellationtoken.IsCancellationRequested)
{
Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++);
Thread.Sleep(); if ( i == )
{
//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;
}
}
}

输出:

// :: PM - DoWork_0
// :: PM - Message_0
// :: PM - Message_1
// :: PM - DoWork_1
// :: PM - Message_2
// :: PM - Message_3
// :: PM - DoWork_2
// :: PM - Message_4
// :: PM - Message_5
// :: PM - DoWork_3
// :: PM - Message_6
// :: 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.)的更多相关文章

  1. Akka(26): Stream:异常处理-Exception handling

    akka-stream是基于Actor模式的,所以也继承了Actor模式的“坚韧性(resilient)”特点,在任何异常情况下都有某种整体统一的异常处理策略和具体实施方式.在akka-stream的 ...

  2. Exception Handling Considered Harmful

    异常处理被认为存在缺陷 Do, or do not. There is no try. - Yoda, The Empire Strikes Back (George Lucas) by Jason ...

  3. C#编程.异常处理(Exception Handling Statements)

    C#语言包含结构化异常处理(Structured Exception Handling,SEH). throw The throw statement is used to signal the oc ...

  4. 异常处理与MiniDump详解(3) SEH(Structured Exception Handling)

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 一.   综述 SEH--Structured Exception Handlin ...

  5. Exception handling 异常处理的本质

    异常处理的本质:状态回滚或者状态维护. https://en.wikipedia.org/wiki/Exception_handling In general, an exception breaks ...

  6. Exception Handling in ASP.NET Web API webapi异常处理

    原文:http://www.asp.net/web-api/overview/error-handling/exception-handling This article describes erro ...

  7. C# to IL 10 Exception Handling(异常处理)

    Exception handling in IL is a big let down. We expected a significant amount of complexity,but were ...

  8. Exception Handling引入MVP

    异常处理(Exception Handling)是所有系统的最基本的基础操作之一,其它的比如日志(Logging).审核(Auditing).缓存(Caching).事务处理(Transaction) ...

  9. Unity、Exception Handling引入MVP

    什么是MVP?在“MVP初探”里就有讲过了,就是一种UI的架构模式. 简单的描述一下Unity和Exception Handling Application Block: Unity是一个轻量级的可扩 ...

随机推荐

  1. hibernate FetchType理解

    JPA定义实体之间的关系有如下几种: @OneToOne @ManyToOne @OneToMany @ManyToMany 在定义它们的时候可以通过fetch属性指定加载方式,有两个值: Fetch ...

  2. HDU 4939 Stupid Tower Defense (2014 Multi-University Training Contest 7)

    思路:首先红色肯定要放在最后面.前面蓝色和绿色dp求解. dp[i][j]  表示前面(i+j) 个 有 i 个蓝色塔  j个绿色塔 能造成最大伤害. //====================== ...

  3. SharePoint\O365 CSOM操作"请求访问设置"功能

    博客地址:http://blog.csdn.net/FoxDave 请求访问设置是在SharePoint网站权限菜单中的一个功能,如下图: 它用来设置成员是否可以共享网站以及个别文件和文件夹,是否允许 ...

  4. SharePoint 2013 开发——搜索架构及扩展

    博客地址:http://blog.csdn.net/FoxDave SharePoint 2013高度整合了搜索引擎,在一个场中只有一个搜索服务应用程序(SSA).它集成了FAST,只有一个代码库 ...

  5. iOS view 颜色渐变

    //渐变色过渡自然 CAGradientLayer *layer = [CAGradientLayer layer]; layer.frame = CGRectMake(0, 0, curW-10,4 ...

  6. iOS内部跳转问题

    //打开地图       NSString*addressText = @" "; //@"1Infinite Loop, Cupertino, CA 95014&quo ...

  7. php-数据库访问--增、删、改

    建立一个登录页面 <form action="chuli.php" method="post"> <div>用户名:<input ...

  8. border-image(转载)

    本文转自:http://www.zhangxinxu.com/wordpress/2010/01/css3-border-image%E8%AF%A6%E8%A7%A3%E3%80%81%E5%BA% ...

  9. Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

  10. 基于redis的排行榜设计和实现

    前言: 最近想实现一个网页闯关游戏的排行榜设计, 相对而言需求比较简单. 秉承前厂长的训导: “做一件事之前, 先看看别人是怎么做的”. 于是乎网上搜索并参考了不少排行榜的实现机制, 很多人都推荐了r ...