[英]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.