在RunWorkerCompleted
事件中重新拋出異常時,我遇到了BackgroundWorker
或.NET框架的奇怪行爲。RunWorkerCompleted未在主UI線程中執行?
發生在後臺線程中的異常傳遞給RunWorkerCompleted
。在那裏我做了一個object temp = e.Result
重新拋出異常。因爲這應該發生在主UI線程中,所以我期望異常被傳播到Application.Run(...)
,我用try-catch塊包圍它。
在Visual Studio中運行應用程序時,此工作正常。但是,當我在Visual Studio之外執行exe文件時,異常不會被處理並使應用程序崩潰。
難道RunWorkerCompleted
事件是而不是在主UI線程中執行?
這些職位不重複,而是確認我的情況是怪異:
- C# BackgroundWorker RunWorkerCompleted Event
- Events raised by BackgroundWorker not executed on expected thread
這是再現錯誤中有着非常簡單的代碼示例:創建WinForms項目並添加:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Form form = new Form();
form.Load += delegate
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (sender, e) =>
{
// do nothing
};
bw.RunWorkerCompleted += (sender, e) =>
{
throw new Exception("Booo!");
};
bw.RunWorkerAsync();
};
Application.Run(form);
}
catch (Exception ex)
{
while (ex is TargetInvocationException && ex.InnerException != null)
ex = ex.InnerException;
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
然後嘗試:
- 在Visual Studio中運行它。在應用程序退出之前,您會收到一個友好的消息框。
- 在Visual Studio外運行編譯的可執行文件。你會得到一個.NET框架「未處理的異常」消息。
有趣的部分是,如果我在2中點擊「繼續」,應用程序仍然存在,並顯示窗體並接受用戶輸入。這意味着不是主UI線程,後臺線程崩潰了。主線程仍然活着。 (爲什麼我想要做所有這些事情?我顯示一個啓動畫面,並且一些應用程序啓動工作在後臺完成時,啓動畫面通過標籤和進度條顯示進度。必須創建並顯示啓動畫面,然後獲取主UI線程以啓動BackgroundWorker
。在原始代碼中,它將報告進度返回到更新啓動窗體的主線程。如果在啓動期間發生異常,我想要捕獲它。在某些情況下,它們是「業務例外」,具有特定含義,例如「您無權使用此應用程序」。在這些情況下,我會在應用程序死前顯示一個友好的消息框。此外,我有一個finally
塊清理資源我不確定.NET框架「未處理的異常」對話框是否執行finally b在殺死應用程序之前鎖定)。
你能制定一個問題嗎? – 2010-10-22 14:49:49
@Pieter:我做了,它是粗體。 – chiccodoro 2010-10-22 14:50:32