簡體   English   中英

BackgroundWorker線程必須是STA

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM