簡體   English   中英

WPF應用程序中的后台線程和UI線程

[英]Background and UI Threads in a WPF Application

我正在閱讀DataModel-View-ViewModel模式:2

我不太了解是否需要檢查我是否在UI或Background線程中。 如果我跳過支票怎么辦。 另外,下面的代碼...

[Conditional("Debug")]
protected void VerifyCalledOnUIThread()
{
    Debug.Assert(Dispatcher.CurrentDispatcher == this.Dispatcher,
        "Call must be made on UI thread.");
}

並沒有真正做任何事情,例如。 設置值。 所以,如果我不調試,它會做什么呢?

我不太了解是否需要檢查我是否在UI或Background線程中。 如果我跳過支票怎么辦。

使用Dispatcher並檢查您是否在UI或后台線程上的原因是由於WPF的要求,即只能在創建控件的線程上訪問控件。 這樣做的原因是因為控件不是線程安全的。 如果您不執行多線程處理(即,所有代碼都在主線程上),則不必擔心這一點。 WinForms具有相同的限制。

如果您嘗試從不同於在其上創建控件的線程訪問控件,則會收到InvalidOperationException

另外,下面的代碼...實際上並沒有做任何事情,例如。 設置值。 所以,如果我不調試,它會做什么呢?

編譯發行版本時, Debug.Assert (和您的VerifyCalledOnUIThread方法)甚至不會出現在代碼中,因此不會,什么也不會發生。

如果您正在使用其他線程,則只需要擔心這一點。 如果您未明確執行此操作,則可能正在使用UI線程。

一些異步操作回調(例如Web服務/ wcf調用)在UI線程上處理。 另外,如果使用計時器(例如DispatchTimer),則它也位於UI線程上。 最后,如果您使用BackgroundWorker線程,則也將在UI線程上進行處理。

希望這可以幫助。

抱歉,但我不同意Chris Schmich。

您可以看到VerifyCalledOnUIThread()出現在DataModel 實際上,目的是僅從UI Thread訪問“非常數據模型”(而不是控件) 是的WPF / SilverLight UI不是跨線程安全的,但這不是真正的原因。

事實是,如果您將某些東西(數據模型/視圖模型)綁定到WPF / SilverLight UI,並且從UI線程之外的其他線程訪問它,那么您將獲得無信息的異常。 解決此錯誤非常困難,因為拋出Exception並沒有提供任何線索。

我給你舉個例子:

//pass model to datacontex and bind it 
mycontrol.DataContext = myModel;

//myThreadedService is an assynchronous service
//done ini different thread.
//so ServiceDone will call myModel.Complete from different thread
//system will crash unexpectedly without enough clue
myThreadedService.ServiceDone += (s, e) => { myModel.Complete = true; }
myThreadedService.CallService();

因此,我認為您現在了解了為什么這段代碼應該存在:

Debug.Assert(Dispatcher.CurrentDispatcher == this.Dispatcher,
        "Call must be made on UI thread.");

當您從其他線程訪問DataModel時,此代碼將提供線索。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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