如何在单个 catch 块中处理来自工作线程和主线程的异常?
Posted
技术标签:
【中文标题】如何在单个 catch 块中处理来自工作线程和主线程的异常?【英文标题】:How do I handle exceptions from worker threads and main thread in a single catch block? 【发布时间】:2016-03-17 07:13:36 【问题描述】:我有 15 个工作线程同时运行。代码在 SSIS 包中运行,我必须保持主线程运行,直到所有工作线程都成功完成或因错误而终止。
为了从工作线程中捕获异常,我有一个静态异常
static Exception Main_Exception = null;
由工作线程更新。
catch (Exception ex)
Main_Exception = ex;
主要方法检查 Main_Exception 是否仍为 null 或已更新。
if (Main_Exception != null)
...
对于出现的任何异常,我需要将异常详细信息插入错误日志。我想管理 main 方法的 catch 块中的所有异常。
我设计了下面的主要方法。方法是正确的还是我错过了什么?在这种情况下,“throw Main_Exception”或“throw”能正常工作吗?
main()
try
if (Main_Exception != null)
throw Main_Exception; OR throw;
catch(Exception ex)
//INSERT exception-details into error-log
【问题讨论】:
【参考方案1】:您无法管理在主应用程序的后台工作线程上引发的异常。
您将不得不在线程本身中处理它们。
如果您希望所有日志记录在一个地方,那么您将不得不执行以下操作:
-
处理线程中的异常,收集您需要记录的信息并保存。
在监控线程(即对线程事件做出反应)的代码中,读取此错误状态并抛出包含必要信息的新异常。
这将被处理并记录在您的全局异常处理程序中。
【讨论】:
为什么他不能只在主线程中为他们.Wait()
(或等待),这会导致他们在主线程中抛出一个AggregateException
,他可以捕获或继续执行完成了吗?
chrisf,谢谢你的回答。根据第二个选项,我是否必须手动创建一个新的 Ecpetion 然后将其放入 if 块中?我的理解对吗? if (Main_Exception != null) throw new Exception();
@BenjaminGruenbaum ,如果我的任何工作线程中有任何异常,我需要整个 SSIS 脚本包以错误结束。需要这样我不能等待其他线程的完成。
@Abhirup 对,因为您有 Task.WhenAll
和 Task.WaitAll
,具体取决于您处于阻塞或非阻塞环境中。
@BenjaminGruenbaum,我是多线程概念的新手,我不知道如何实现 Task.WhenAll 和 Task.WaitAll。我之前曾试图通过 Parallel.ForEach(SomeTask=> ...) 来解决这种情况,但它没有运行,据说是导致 .net 版本
【参考方案2】:
第一个想法似乎是将每一个异常记录在它自己的线程中。
无论如何,如果您需要跟踪多个异常,请考虑使用AggregateException
类。
您可以保留一个List<Exception> m_AllExceptions
(或者更好的SynchronizedCollection<Exception>
,因为您将从多个线程访问它)来代替您的变量MainThreadException
然后在主线程中检查异常时,您可以使用以下内容:
if (m_AllExceptions.Count > 0 != null)
AggregateException ex = new AggregateException(m_AllExceptions);
throw ex;
【讨论】:
以上是关于如何在单个 catch 块中处理来自工作线程和主线程的异常?的主要内容,如果未能解决你的问题,请参考以下文章
在线程中处理在 catch 块中抛出的异常的最佳实践。 (。网)
JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗