[英]BackgroundWorker thread must be STA
我有一個BackgroundWorker調用函數在BackgroundWorker _DoWork上執行一個很長的過程,當函數出錯時我會提示自定義的消息框:
WPFMessageBoxResult result = WPFMessageBox.Show("Activation Fail", "Error!!", WPFMessageBoxButtons.OK, WPFMessageBoxImage.Error);
以下例外發生在WPFMessageBoxResult類:
The calling thread must be STA, because many UI components require this.
謝謝。
您不應嘗試與后台線程中的任何UI組件進行交互。
一種方法是在doWork方法中捕獲異常並將其分配給backgroundworker的result屬性,然后檢查該結果是否是一種異常,如果您沒有將結果用於其他任何內容,則不為null。 然后在backgroundWorker_completed事件中檢查它。
BackgroundWorker_DoWork(sender, )
{
try
{
// do work
}
catch (Exception ex)
{
BackgroundWorker w = sender as BackgroundWorker;
if (w != null)
w.Result = ex;
}
}
然后
BackgroundWorker_Completed()
{
if (s.Result != null && e.Result is Exception)
{
Exception ex = e.Result as Exception;
// do something with ex
}
}
通常使用Winforms / WPF,如果需要從長時間運行的任務中與UI進行交互,則使用Invoke()跳轉到UI線程。 您可以從屬於UI的任何對象調用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);
});
}
}
您的后台線程只是一個工作線程而不是用戶界面線程。 WPF和WinForms都要求執行用戶界面操作的線程被標記為STA(單線程單元),因為用戶界面代碼不是線程安全的。 它們還要求您添加消息泵以便分派Windows消息。
我建議您不要在工作線程中顯示消息框,而是向主用戶界面線程發送消息並讓該線程顯示消息框。 為此,您應該將Dispatcher的引用從主UI線程傳遞到工作線程。 然后使用Dispatcher.BeginInvoke請求在主線程上回調委托。
或者,您可以等待后台線程完成,然后檢查結果並向用戶顯示相應的答案。 無論哪種方式,工作線程都不應該直接與用戶界面交互。
您必須使用此方法
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.