Pet*_*lly 5 c# multithreading backgroundworker
我想在后台线程上运行一个操作.当它完成后,我想检查发生的任何错误,并将它们重新抛出我的原始线程.
我正在使用背景工作者.在RunWorkerCompleted事件处理程序中抛出异常会导致未处理的异常 - 如果事件处理程序在后台线程上运行,这是有意义的.如果我有一个winform控件,我可以调用Invoke或BeginInvoke,但我没有在这个对象中使用winform控件,尽管它是一个winform项目.
如何重新抛出backgroundworker中发生的异常?
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// I want to throw an exception here, without causing an unhandled exception and without being able to call Invoke or BeginInvoke on a WinForm control.
}
else if (e.Cancelled)
{
// Do something useful
}
else
{
if (e.Result != null)
{
// Do something with the result
}
}
}
Run Code Online (Sandbox Code Playgroud)
我原以为RunWorkerCompleted事件处理程序将在原始调用线程上运行.也许背景工作者不是我在这种情况下所需要的.
将代码注入另一个正在运行的线程是不可能的.甚至操作系统也无法做到这一点.
Control.BeginInvoke的工作原理是将委托引用放入队列,然后使用PostMessage将用户消息发布到UI线程的消息队列中.Application.Run消息循环查找此消息,当它发现它将队列弹出队列并执行它.
关键是没有其他方法可以做你需要的,而不需要对主线程进行编码,以便从另一个线程中寻找某种信号(或消息).
添加
您声明这是一个WinForm应用程序,但您没有控件使用BeginInvoke.
编辑:我提出了一个懒惰的负载而没有考虑它.Control最终可能会在错误的线程上创建.
Application.Run在应用程序的生命周期之前预先创建一个控件.您可以将此用于BeginInvoke.
编辑#3
所以,然后我尝试这一点,以确保它的工作,当然,它没有.你不能简单地创建一个通用的Control,它必须有一个HWND句柄.简单修复:像这样创建它:
invokerControl = new Control();
invokerControl.CreateControl();
Run Code Online (Sandbox Code Playgroud)
这将允许您从它开始BeginInvoke,即使没有要调用的打开Form对象.
| 归档时间: |
|
| 查看次数: |
5858 次 |
| 最近记录: |