捕获在不同线程中抛出的异常
我的一个方法 (Method1
) 生成一个新线程。
该线程执行一个方法 (Method2
),并在执行期间引发异常。
我需要获取有关调用方法的异常信息 (Method1
)
是否可以通过某种方式捕获 Method1
中在 Method2
中引发的异常?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在.NET 4及更高版本中,您可以使用
Task
类而不是创建新线程。然后,您可以使用任务对象上的 .Exceptions 属性来获取异常。有两种方法可以做到这一点:
在单独的方法中: // 在某些任务的线程中处理异常
在同一方法中: // 在调用者线程中处理异常强>线程
请注意,您得到的异常是
AggregateException
。所有真正的异常都可以通过 ex.InnerExceptions 属性获得。在.NET 3.5中,您可以使用以下代码:
//您在子线程中处理异常
或者 // 您在调用者线程中处理异常
In .NET 4 and above, you can use
Task<T>
class instead of creating new thread. Then you can get exceptions using.Exceptions
property on your task object.There are 2 ways to do it:
In a separate method: // You process exception in some task's thread
In the same method: // You process exception in the caller's thread
Note that the exception which you get is
AggregateException
. All real exceptions are availible throughex.InnerExceptions
property.In .NET 3.5 you can use the following code:
// You process exception in the child's thread
Or // You process exception in the caller's thread
您无法捕获 Method1 中的异常。但是,您可以捕获 Method2 中的异常并将其记录到原始执行线程可以读取和使用的变量中。
You can not catch the exception in Method1. You can, however, catch the exception in Method2 and record it to a variable that the original thread of execution can then read and work with.
我有一个特殊的问题,因为我想使用集成测试套件中包含控件的项目,因此必须创建一个 STA 线程。我最终得到的代码如下,放在这里以防其他人遇到同样的问题。
这是直接粘贴代码。对于其他用途,我建议提供一个操作或函数作为参数,并在线程上调用它,而不是对被调用的方法进行硬编码。
I had a particular problem in that I wanted to use items, containing controls, from an integration test suite, so have to create an STA thread. The code I ended up with is as follows, put here in case others have the same issue.
This is a direct paste of the code as-is. For other uses I would recommend supplying an action or function as a parameter and invoking that on the thread instead of hard-coding the called method.
在不同线程之间共享数据的最简单方法是
共享数据
,如下所示(有些是伪代码):您可以在 关于多线程的精彩介绍,但是,我更喜欢在
O'Reilly 的书《C# 3.0》中阅读有关此内容的内容简而言之,作者是 Albahari 兄弟(2007 年),它也可以在 Google 图书上免费访问,就像这本书的新版本一样,因为它还涵盖了线程池、前台线程与后台线程等内容,并且具有良好的和简单的示例代码。 (免责声明:我拥有这本书的一本破旧副本)
如果您正在制作 WinForms 应用程序,则使用共享数据特别方便,因为 WinForm 控件不是线程安全的。使用回调将数据从工作线程传递回 WinForm 控件,主 UI 线程需要带有
Invoke()
的丑陋代码才能使该控件线程安全。使用共享数据和单线程System.Windows.Forms.Timer
(例如 0.2 秒的短Interval
),您可以轻松地从工作线程发送信息到没有Invoke
的控件。The simplest method to share data between different threads is
shared data
as follows (some is pseudo code):You can read about this method in this nice introduction about multithreading, however, I preferred to read about this in the
O'Reilly book C# 3.0 in a nutshell
, by the brothers Albahari (2007), which is also freely accessible on Google Books, just like the newer version of the book, because it also covers thread pooling, foreground versus background threads, etc etc, with nice and simple example code. (Disclaimer: I own a worn-out copy of this book)In case you are making a WinForms application, the use of shared data is especially handy, because the WinForm controls are not thread-safe. Using a callback to pass data from the worker thread back to a WinForm control the main UI thread needs ugly code with
Invoke()
to make that control thread-safe. Using shared data instead, and the single-threadedSystem.Windows.Forms.Timer
, with a shortInterval
of say 0.2 seconds, you can easily send information from the worker thread to the control withoutInvoke
.这是我用来将异常抛出回主线程以进行捕获的代码。
Here is the code that I used to throw the exception back to the main thread to be caught.