C# ThreadPool QueueUserWorkItem 异常处理
Posted
技术标签:
【中文标题】C# ThreadPool QueueUserWorkItem 异常处理【英文标题】:C# ThreadPool QueueUserWorkItem Exception Handling 【发布时间】:2011-07-10 05:43:36 【问题描述】:每当我的 ThreadPool 中的线程抛出异常时,我的代码似乎就会卡在线程函数内的 catch 块中。如何将异常返回到主线程?
【问题讨论】:
复制:***.com/questions/753841/… How to catch exceptions from a ThreadPool.QueueUserWorkItem?的可能重复 那些方法不起作用。我得到一个例外说The calling thread must be STA, because many UI components require this.
好的,可能值得发布一些代码。听起来您可能正在从非 GUI 线程访问 GUI 组件。
我正在访问一个列表框以从线程中添加异常。如果我直接把它卡在线程捕获块中,它就不会回到主线程
【参考方案1】:
最佳做法是您的后台线程不应抛出异常。让他们自己处理异常。
理想情况下,您应该将代码包装在您的方法中,该方法在 try-catch 块中的线程上执行,并在 catch 块中处理异常。不要从 catch 块中重新抛出它。
阅读本文了解更多详情。 http://www.albahari.com/threading/#_Exception_Handling
如果您想从后台线程更新 UI,您可以使用 Control.InvokeRequired 属性和 Control.Invoke 方法来实现。有关详细信息和示例,请参阅 MSDN 链接。
【讨论】:
但我的 UI 必须显示异常。我能做什么? 在线程中捕获它并使用队列(管道)将消息发送回UI线程以显示错误。线程边界上的异常是一件坏事,而且很难解决。【参考方案2】:不可能将异常从一个线程转移到另一个线程。你可以做的是建立一些同步机制来在线程之间传输异常信息,然后从目标线程抛出一个新的异常,例如:
class Program
Exception _savedException = null;
AutoResetEvent _exceptionEvent = new AutoResetEvent(false);
static void Main(string[] args)
Program program = new Program();
program.RunMain();
void RunMain()
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod));
while (true)
_exceptionEvent.WaitOne();
if (_savedException != null)
throw _savedException;
void ThreadMethod(object contxt)
try
// do something that can throw an exception
catch (Exception ex)
_savedException = ex;
_exceptionEvent.Set();
如果您有一个 Win 表单应用程序,事情就简单多了。在线程的 catch 子句中,使用表单的 Invoke(或 BeginInvoke)方法,为其提供异常详细信息。在使用 Invoke 启动的方法中,您可以根据需要重新抛出或处理您的异常。
【讨论】:
以上是关于C# ThreadPool QueueUserWorkItem 异常处理的主要内容,如果未能解决你的问题,请参考以下文章
C# ThreadPool QueueUserWorkItem 异常处理