wpf BackgroundWorker 线程必须是 STA
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12719970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BackgroundWorker thread must be STA
提问by Alvin
I have a BackgroundWorker to call a function to do a long process at BackgroundWorker _DoWork, when error occur in the function I will prompt a customized messagebox:
我有一个BackgroundWorker来调用一个函数在BackgroundWorker _DoWork上做一个很长的过程,当函数发生错误时,我会提示一个自定义的消息框:
WPFMessageBoxResult result = WPFMessageBox.Show("Activation Fail", "Error!!", WPFMessageBoxButtons.OK, WPFMessageBoxImage.Error);
The exception below happens at WPFMessageBoxResult class :
以下异常发生在 WPFMessageBoxResult 类:
The calling thread must be STA, because many UI components require this.
Thank you.
谢谢你。
回答by John L
You should not try to interact with any UI components from a background thread.
您不应尝试从后台线程与任何 UI 组件进行交互。
One way could be to catch the exception in your doWork method and assign it to the backgroundworker's result property and then check if that result is a type of exception or not null if you are not using the result for anything else. then check for it in the backgroundWorker_completed event.
一种方法可能是在您的 doWork 方法中捕获异常并将其分配给后台工作人员的结果属性,然后检查该结果是否是一种异常类型,或者如果您不将结果用于其他任何事情,则检查该结果是否为空。然后在 backgroundWorker_completed 事件中检查它。
BackgroundWorker_DoWork(sender, )
{
try
{
// do work
}
catch (Exception ex)
{
BackgroundWorker w = sender as BackgroundWorker;
if (w != null)
w.Result = ex;
}
}
then
然后
BackgroundWorker_Completed()
{
if (s.Result != null && e.Result is Exception)
{
Exception ex = e.Result as Exception;
// do something with ex
}
}
回答by Despertar
Usually with Winforms/WPF you use Invoke() to jump onto the UI thread if you need to interact with the UI from a long-running task. You can call invoke from any object that belongs to the UI, but be sure when in the invoke scope to only do as little code as possible. Since this code is on the UI thread it will block/hang the UI if it takes too long.
如果您需要从长时间运行的任务中与 UI 交互,通常使用 Winforms/WPF 您可以使用 Invoke() 跳转到 UI 线程。您可以从属于 UI 的任何对象调用 invoke,但请确保在 invoke 范围内只执行尽可能少的代码。由于此代码位于 UI 线程上,因此如果花费太长时间,它将阻塞/挂起 UI。
public void BackgroundWorkerMethod()
{
try
{
// do work
}
catch (Exception e)
{
uiObject.Invoke(new Action(() => {
// now you are on the UI thread
Message.ShowMessage(e.Message);
});
}
}
回答by reza
You must use this method
你必须使用这个方法
void BGW_DoWork(object sender, DoWorkEventArgs e)
{
try
{
Dispatcher.BeginInvoke(new Action(() =>
{
Button btn = new Button();
btn.Width = 100;
btn.Height = 50;
btn.Content = "Test";
myG.Children.Add(btn);
}
));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
回答by Phil Wright
Your background thread is just a worker thread and not a user interface thread. WPF and WinForms both require that the thread performing user interface actions be marked as STA (Single Threaded Apartment) because the user interface code is not thread safe. They also require that you add a message pump so that windows messages are dispatched.
您的后台线程只是一个工作线程,而不是用户界面线程。WPF 和 WinForms 都要求将执行用户界面操作的线程标记为 STA(单线程单元),因为用户界面代码不是线程安全的。它们还要求您添加消息泵,以便分派 Windows 消息。
I recommend that instead of showing the message box in your worker thread you send a message to your main user interface thread and have that thread show the message box. To do this you should pass a reference to the Dispatcher from the main UI thread into the worker thread. Then use the Dispatcher.BeginInvoke to request a delegate be called back on the main thread.
我建议不要在工作线程中显示消息框,而是向主用户界面线程发送一条消息,并让该线程显示消息框。为此,您应该将从主 UI 线程对 Dispatcher 的引用传递到工作线程。然后使用 Dispatcher.BeginInvoke 请求在主线程上回调委托。
Alternatively you can wait for the background thread to complete and then check the result and show the appropriate answer to the user. Either way the worker thread should not be directly interacting with the user interface.
或者,您可以等待后台线程完成,然后检查结果并向用户显示适当的答案。无论哪种方式,工作线程都不应该直接与用户界面交互。

