[英]WPF CrossThreadException in App.Xaml with BackgroundWorker
我的App.Xaml中有這個:
public App()
{
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += new DoWorkEventHandler(DoBackgroundWork);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundCompleted);
_backgroundWorker.RunWorkerAsync();
_splashView = new SplashView();
_splashView.Show();
}
DoBackgroundWork
方法執行一些數據庫設置,然后BackgroundCompleted
事件關閉_splashView
並顯示_mainView
。
但是,從BackgroundCompleted
修改_splashView
任何內容_splashView
導致跨線程異常,這是我設計了后台工作程序修復的。 我猜想這與App.Xaml
backgroundworker的工作方式App.Xaml
。 也許這是做啟動畫面的壞方法?
后台工作者使用SynchronizationContext。 這是從內存中進行的,但我認為它尚未在App構造函數中初始化。
在構造BW之前,請檢查SynchronizationContext.Current不為null。 還要在構造BW之前和完成的方法中檢查SynchronizationContext.Current是否相同。
如果不是,則需要在此過程中稍后移動代碼... App.OnStartUp應該很好
也許這是做啟動畫面的壞方法?
除非我對您的問題有誤解,否則我認為不需要顯示初始屏幕。 只需選擇圖像,然后在“屬性”窗口中單擊BuildAction
下拉列表,然后選擇SplashScreen
。 另外,我認為您可以通過消除BackgroundWorker
來簡化流程,除非您的數據功能花費很長時間。 我相信您已添加它以適應初始屏幕的顯示/隱藏。
無法保證OnWorkCompleted
的事件處理程序將使用哪個線程執行。
看到類似的問題BackgroundWorker OnWorkCompleted引發跨線程異常
您必須使用Invoke
或BeginInvoke
方法來修改后台線程中的視覺元素。 您可以直接在要修改其屬性的對象上調用此方法,也可以使用Dispatcher
。
編輯:根據與亞當的對話
對於在初始線程(而不是BackgroundWorker的線程)上運行OnWorkCompleted
事件處理程序, SynchronizationContext
具有所需的效果。 http://msdn.microsoft.com/zh-CN/magazine/gg598924.aspx 。 (見圖2)
如果BackgroundWorker是在SynchronizationContext初始化之前創建並運行的,則OnWorkCompleted
將在與BackgroundWorker相同的線程上執行。
謝謝亞當。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.