[英]Can I initialize ViewModel from a worker thread?
I am designing a WPF application following MVVM pattern. 我正在按照MVVM模式设计WPF应用程序。 But when it comes to multi-threading issue, I find my knowledge quite limited.
但是当涉及到多线程问题时,我发现我的知识非常有限。 My question is exactly like the title: can I create the
ViewModel
objects in a worker thread? 我的问题与标题完全一样:我可以在工作线程中创建
ViewModel
对象吗?
Currently we are not using any dependency injection so I just create the ViewModel object in the constructor of the View
in UI thread (I guess it is not the best practice). 当前,我们没有使用任何依赖注入,因此我只是在UI线程中的
View
的构造函数中创建ViewModel对象(我认为这不是最佳实践)。 But now there is a problem: we have one core class, let's call it CoreContext
, from our legacy software which is responsible for many core tasks, Data Access Layer between our SW and database is one of them. 但是现在出现了一个问题:我们有一个核心类,我们可以将其
CoreContext
,它来自负责许多核心任务的旧版软件,软件与数据库之间的数据访问层就是其中之一。 Many of our ViewModel
hold one reference to CoreContext
as data member. 我们的许多
ViewModel
CoreContext
一个对CoreContext
引用作为数据成员。 Unfortunately this class is not built thread-safe. 不幸的是,该类不是线程安全的。 When I create the
ViewModel
instance(and hence the CoreContext
instance) in UI thread, it is guaranteed that CoreContext
is only accessed in the owning thread. 当我在UI线程中创建
ViewModel
实例(并因此创建CoreContext
实例)时,可以确保仅在拥有线程中访问CoreContext
。 However, when it involves with some heavy database query, the UI becomes not responsive. 但是,当它涉及一些繁重的数据库查询时,UI不会响应。
So now I am wondering, is it possible to instantiate the ViewModel
(hence the CoreContext
instance) in a non-UI thread so the UI can be responsive when the VM(ultimately the CoreContext
) is making heavy query? 所以现在我想知道,是否可以在非UI线程中实例化
ViewModel
(因此为CoreContext
实例),以便在VM(最终为CoreContext
)进行大量查询时UI可以响应?
I don't think it's a good idea to create and update the ViewModel on a non-UI thread. 我认为在非UI线程上创建和更新ViewModel不是一个好主意。 However, nothing actually prevents you from doing so, if you really have to.
但是,如果确实需要,实际上没有什么可以阻止您这样做。 You would just need to make the whole
ViewModel
thread-safe, ie, use proper locks everywhere you access the data fields, including property getter/setters. 您只需要使整个
ViewModel
线程安全的即可,即,在访问数据字段的任何地方都使用适当的锁,包括属性getter / setter。 That should be done for the whole ViewModel
object hierarchy. 这应该在整个
ViewModel
对象层次结构中完成。
The WPF framework will automatically marshal INotifyPropertyChanged.PropertyChanged
notifications for the data-bound UI controls (at least, in .NET 4.5, AFAIK). WPF框架将自动
INotifyPropertyChanged.PropertyChanged
数据绑定的UI控件的INotifyPropertyChanged.PropertyChanged
通知(至少在.NET 4.5中为AFAIK)。 This way, the controls will be updating themselves automatically on the main UI thread, as expected. 这样,控件将按预期在主UI线程上自动更新自己。
What's important: if setting or getting any ViewModel property initiates a background operation involving your legacy Data Access Layer, you'd have to carry on such operation on the same thread your Data Access Layer was originally created on. 重要的是:如果设置或获取任何ViewModel属性会启动涉及旧数据访问层的后台操作,则您必须在最初创建数据访问层的同一线程上进行此类操作。 That is, implement thread affinity for it.
也就是说,为其实现线程关联。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.