簡體   English   中英

帶有BackgroundWorker的App.Xaml中的WPF CrossThreadException

[英]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引發跨線程異常

您必須使用InvokeBeginInvoke方法來修改后台線程中的視覺元素。 您可以直接在要修改其屬性的對象上調用此方法,也可以使用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.

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