Использование MVVM на самом деле довольно просто. Что я делаю, так это помещаю что-то вроде следующего в, скажем, ViewModelBase ...
protected readonly SynchronizationContext SyncContext = SynchronizationContext.Current;
или ...
protected readonly TaskScheduler Scheduler = TaskScheduler.Current;
Тогда, когда конкретному ViewModel нужно дотронуться до чего-нибудь «наблюдаемого», вы можете проверить контекст и соответственно отреагировать ...
public void RefreshData(object state = null /* for direct calls */)
{
if (SyncContext != SynchronizationContext.Current)
{
SyncContext.Post(RefreshData, null); // SendOrPostCallback
return;
}
// ...
}
или сделать что-то еще в фоновом режиме, прежде чем вернуться в контекст ...
public void RefreshData()
{
Task<MyData>.Factory.StartNew(() => GetData())
.ContinueWith(t => {/* Do something with t.Result */}, Scheduler);
}
Обычно, если вы следуете MVVM (или любой другой архитектуре) упорядоченным образом, легко определить, где будет лежать ответственность за синхронизацию пользовательского интерфейса. Но вы можете сделать это где угодно, чтобы вернуться в контекст, в котором создаются ваши объекты. Я уверен, что было бы легко создать «Guard», который бы справлялся с этим чисто и последовательно в большой и сложной системе.
Я думаю, что имеет смысл сказать, что ваша единственная обязанность - вернуться в свой первоначальный контекст. Это обязанность клиента сделать то же самое.