统一的线程异常处理
来源: 发布时间:星期六, 2009年12月26日 浏览:0次 评论:0
在 ![](/icons/54608yi.gif) 个Service ![](/icons/54608chengxu.gif) 中 ![](/icons/54608dou.gif) 通常都会有多个Worker线程 ![](/icons/54608dou.gif) 它们可能单独运行 ![](/icons/54608dou.gif) 也可能在 ![](/icons/54608yi.gif) 个ThreadPool中运行 ![](/icons/54608dou2.gif) 为了不至于使Worker线程 ![](/icons/54608de.gif) 未处理异常导致主 ![](/icons/54608chengxu.gif) ![](/icons/54608de.gif) 崩溃 ![](/icons/54608dou.gif) 我们需要对所有 ![](/icons/54608de.gif) 工作线程以 ![](/icons/54608yi.gif) 种 ![](/icons/54608yi.gif) 致 ![](/icons/54608de.gif) 方式处理异常 ![](/icons/54608dou.gif) 例如通知主线程 ![](/icons/54608dou.gif) 然后根据区别 ![](/icons/54608de.gif) 异常做区别 ![](/icons/54608de.gif) 处理 ![](/icons/54608dou.gif) 最后优雅地停止该有问题 ![](/icons/54608de.gif) 线程 ![](/icons/54608dou2.gif) 例如以下 ![](/icons/54608chengxu.gif) : void Main( ![](/icons/54608string.gif) args)
{
Thread thread1 = Thread(( ThreadStart) Worker_1);
thread1.Start![](/icons/54608kh.gif) ;
Thread thread2 = Thread(( ThreadStart) Worker_2);
thread2.Start![](/icons/54608kh.gif) ;
thread1.Join![](/icons/54608kh.gif) ;
thread2.Join![](/icons/54608kh.gif) ;
}
void Worker_1![](/icons/54608kh.gif)
{
try
{
// Do something here.
}
catch ( Exception e)
{
// TODO, handler exception,
// Not y the thread and stop this thread gracefully.
}
}
void Worker_2![](/icons/54608kh.gif)
{
try
{
// Do something here.
}
catch ( Exception e)
{
// TODO, handler exception,
// Not y the thread and stop this thread gracefully.
}
}
在该 ![](/icons/54608chengxu.gif) 中 ![](/icons/54608dou.gif) 我们有 Worker_1 和 Worker_2两个工作线程 ![](/icons/54608dou.gif) 它们有相同 ![](/icons/54608de.gif) 异常处理过程 ![](/icons/54608dou2.gif) 但是问题是 ![](/icons/54608dou.gif) 当任务 ![](/icons/54608de.gif) 种类多了起来 ![](/icons/54608dou.gif) 如Worker_3, Worker_4 ![](/icons/54608dou.gif) 所有 ![](/icons/54608de.gif) 这样 ![](/icons/54608de.gif) 线程 ![](/icons/54608hanshu.gif) 都要做相同 ![](/icons/54608de.gif) 异常处理 ![](/icons/54608dou.gif) 就导致了不必要 ![](/icons/54608de.gif) 重复 ![](/icons/54608dou.gif) 并且很容易遗忘 ![](/icons/54608dou2.gif) 怎样去除这种重复呢?首先想到 ![](/icons/54608de.gif) 是 ![](/icons/54608yi.gif) 个方案是 ![](/icons/54608dou.gif) 提供 ![](/icons/54608yi.gif) 个辅助 ![](/icons/54608hanshu.gif) ![](/icons/54608dou.gif) 它接受 ![](/icons/54608yi.gif) 个Action作为参数:
void SafeThread( Action action)
{
try
{
action![](/icons/54608kh.gif) ;
}
catch ( Exception e)
{
// TODO, handler exception,
// Not y the thread and stop this thread gracefully.
}
}
然后Worker_1 可以这么写:
void Worker_1![](/icons/54608kh.gif)
{
SafeThread( delegate
{
// Do something here.
});
}
这样是能简化 ![](/icons/54608yi.gif) 些 ![](/icons/54608dou2.gif) 但这种做法会使原来 ![](/icons/54608de.gif) Worker思路方法有 ![](/icons/54608yi.gif) 个奇怪 ![](/icons/54608de.gif) 包装 ![](/icons/54608dou.gif) 而且依然要求我们对每 ![](/icons/54608yi.gif) 个Worker做同样 ![](/icons/54608de.gif) 处理 ![](/icons/54608dou2.gif) 既然Thread ![](/icons/54608de.gif) 构造 ![](/icons/54608hanshu.gif) 接受 ![](/icons/54608yi.gif) 个 ThreadStart ![](/icons/54608de.gif) 参数 ![](/icons/54608dou.gif) 我们能不能把 ![](/icons/54608yi.gif) 个原始 ![](/icons/54608de.gif) 直接 ![](/icons/54608de.gif) Worker 思路方法(也是 ThreadStart类型)转换为 ![](/icons/54608yi.gif) 个可以处理异常 ![](/icons/54608de.gif) ThreadStart 类型呢? 是可以 ![](/icons/54608de.gif) ![](/icons/54608dou2.gif) 首先我们定义这个转换 ![](/icons/54608hanshu.gif) 如下:
ThreadStart SafeThread( ThreadStart threadStart)
{
=>
{
try
{
threadStart![](/icons/54608kh.gif) ;
}
catch ( Exception e)
{
// TODO, handler exception,
// Not y the thread and stop this thread gracefully.
}
};
}
那么我们 ![](/icons/54608de.gif) Worker线程会很直接:
void Worker_1![](/icons/54608kh.gif)
{
Console.WriteLine( "Worker 1");
// Do something here.
}
void Worker_2![](/icons/54608kh.gif)
{
Console.WriteLine( "Worker 2");
// Do something here.
}
而主 ![](/icons/54608chengxu.gif) 则需要稍加改动 ![](/icons/54608dou.gif) 但也非常简单:
void Main( ![](/icons/54608string.gif) args)
{
Thread thread1 = Thread( SafeThread( Worker_1));
thread1.Start![](/icons/54608kh.gif) ;
Thread thread2 = Thread( SafeThread( Worker_2));
thread2.Start![](/icons/54608kh.gif) ;
thread1.Join![](/icons/54608kh.gif) ;
thread2.Join![](/icons/54608kh.gif) ;
}
这对线程 ![](/icons/54608hanshu.gif) ![](/icons/54608de.gif) 编写者来说 ![](/icons/54608dou.gif) 减轻了很多负担 ![](/icons/54608dou.gif) 也不至于会遗漏掉某个线程没被处理 ![](/icons/54608dou2.gif) 做 ![](/icons/54608yi.gif) 次简单 ![](/icons/54608de.gif) 搜索就可以解决问题 ![](/icons/54608dou2.gif)
对于接受 ![](/icons/54608yi.gif) 个参数 ![](/icons/54608de.gif) 线程(ParameterizedThreadStart)和线程池线程 (WaitCallback) ![](/icons/54608dou.gif) 我们又该如何处理呢?
标签:
相关文章
读者评论
发表评论
|
|