我正在阅读DataModel-View-ViewModel pattern: 2
我真的不明白需要检查我是否在UI或后台线程中。如果我跳过支票怎么办?另外,下面的代码......
[Conditional("Debug")]
protected void VerifyCalledOnUIThread()
{
Debug.Assert(Dispatcher.CurrentDispatcher == this.Dispatcher,
"Call must be made on UI thread.");
}
并没有真正做任何事情,例如。设定值。所以,如果我没有调试它会做任何事情吗?
答案 0 :(得分:4)
我真的不明白需要检查我是否在UI或后台线程中。如果我跳过支票怎么办?
使用Dispatcher
并检查您是否在UI或后台线程上的原因是因为WPF要求只能在创建它们的线程上访问控件。原因是因为控件不是线程安全的。如果您没有进行多线程处理(即所有代码都在主线程上),那么您不必担心这一点。 WinForms也有同样的限制。
如果您尝试从与其创建的线程不同的线程访问控件,您将获得InvalidOperationException
。
此外,下面的代码......并没有真正做任何事情,例如。设定值。所以,如果我没有调试它会做任何事情吗?
在编译发布版本时,Debug.Assert
(以及您的VerifyCalledOnUIThread
方法)甚至不会出现在代码中,所以不会发生任何事情。
答案 1 :(得分:2)
如果您正在使用其他线程,则只需要担心这一点。如果您没有明确地这样做,那么您可能正在使用UI线程。
在UI线程上处理某些异步操作回调,例如Web服务/ wcf调用。 此外,如果您使用计时器,例如DispatchTimer,它也在UI线程上。 最后,如果您使用BackgroundWorker线程,那么也会在UI线程上处理。
希望这有帮助。
答案 2 :(得分:2)
很抱歉,但我不同意Chris Schmich的观点。
您可以看到VerifyCalledOnUIThread()
中显示DataModel
。实际上,目的是 To Veryfy仅从UI线程访问的DataModel(不是控件)。是的WPF / SilverLight UI不是跨线程安全的,但在这种情况下,这不是真正的原因。
事实是,如果您将某些内容(datamodel / viewmodel)绑定到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时,此代码将给出一个线索。