2013-01-16 40 views
0

我有這樣的委託:WPF UI Dispatcher.Invoke通話過程中,unrespoonsive

private delegate void NoArgDelegate(BitmapImage image); 

我實例化的委託,並與Dispatcher.Invoke像這樣運行:

var fetcher = new NoArgDelegate(InstantiateForm); 
Dispatcher.Invoke(fetcher, DispatcherPriority.Normal, imageToPassIn); 

我有一個私人領域在任何方法的範圍之外,但在我的ViewModel的範圍內,在InstantiateForm中實例化對象:

private OmrForm _ormForm; 

private void InstantiateForm(BitmapImage image) 
{ 
    _ormForm = new OmrForm(image); 
} 

這一切都發生在ViewModel中的一個方法中,該方法在我的WPF表單上的按鈕的單擊事件上運行。

我在構造函數中做了一些工作,以計算出我傳入的圖像類型並正確設置了座標,約2秒,並且我希望我的UI在這段時間內響應,但事實並非如此。我試過使用BeginInvoke也無濟於事。

這裏發生了什麼,爲什麼我的方法不是異步運行?

回答

3

在Window或UserControl內調用Dispatcher.Invoke將在UI線程上運行該代碼,因爲控件的Dispatcher被設置爲在UI線程上工作。

你想要的是啓動後臺線程。這可以使用Task類來實現。

Task.Factory.StartNew(() => InstantiateForm(imageToPassIn)); 
1

Dispatcher.Invoke將一個動作放入隊列中以便在UI線程上執行。如果你想執行冗長的計算,你應該在工作者線程中這樣做,這樣UI線程就可以自由地執行其他任務了。你可以例如嘗試ThreadPool.QueueUserWorkItem

0

的問題是,建設一個新Window仍然需要調度員做的工作,因此,如果您Window的構造需要很長的時間來執行,分派仍然會停留在等待該構造函數來完成,儘管以前稱爲Invoke

你想要做的是讓你的構造函數非常快,然後創建一個屬性,你可以使用它來設置圖像,並使該屬性以非時鐘方式執行所有冗長的工作,所以UI線程不是'捆綁起來。

有些人建議使用線程來調用你的方法,但是在不同的線程上創建一個新的Window不是一個好主意,還有其他的含義。