1

I am designing a WPF application following MVVM pattern. 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?

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). 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. Many of our ViewModel hold one reference to CoreContext as data member. 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. However, when it involves with some heavy database query, the UI becomes not responsive.

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?

tete
  • 4,859
  • 11
  • 50
  • 81
  • You might be better off looking at await / async. This would allow your db queries to run asynchronously whilst still all on the GUI thread. – GazTheDestroyer Feb 25 '14 at 12:37
  • @GazTheDestroyer, apparently, the OP deals with the legacy Data Access Layer here, which might not be feasibly converted to `async/await`. – noseratio Feb 25 '14 at 12:40

1 Answers1

2

I don't think it's a good idea to create and update the ViewModel on a non-UI thread. However, nothing actually prevents you from doing so, if you really have to. You would just need to make the whole ViewModel thread-safe, i.e., use proper locks everywhere you access the data fields, including property getter/setters. That should be done for the whole ViewModel object hierarchy.

The WPF framework will automatically marshal INotifyPropertyChanged.PropertyChanged notifications for the data-bound UI controls (at least, in .NET 4.5, AFAIK). This way, the controls will be updating themselves automatically on the main UI thread, as expected.

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. That is, implement thread affinity for it.

noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    Thanks for your answer. That's also how I feel. And that's what's blocking me: we are trying to access data from our DAL class as much as possible since we implement Cache/WeakReference for loading. But since this DAL is not thread safe, sometimes it is hard to use it ion client side. And as you pointed out, since our ViewModel normally have the DAL as member, they should be initiated in the same/dedicated thread – tete Feb 25 '14 at 14:32
  • @tele, this may help to implement thread affinity for your legacy DAL: http://stackoverflow.com/questions/20993007/how-to-use-non-thread-safe-async-await-apis-and-patterns-with-asp-net-web-api – noseratio Feb 28 '14 at 13:53