Внутри ViewModel выполняется асинхронный блок.
Перед этим блоком значение свойства ControlsEnabled меняется на false, внутри этого блока меняется назад на True.
Примерно так:
private void DoTheThing(string clientType)
{
var applicationWorker = new ApplicationWorker();
applicationWorker.StatusUpdated += (sender, s) =>
{
_syncContext.Post(o => StatusText = s, null); // обновление статуса в статусбаре
};
ControlsEnabled = false; // отключаем контролсы
Task.Run(() =>
{
var result = applicationWorker.DoTheThing();
_syncContext.Post(o => ControlsEnabled = true, null); // включаем контролсы (выполнение в потоке UI)
ResetDataToDefaults();
}).ContinueWith((t) =>
{
if (t.IsFaulted) SendFaultLog(t.Exception);
}, TaskScheduler.FromCurrentSynchronizationContext()); ;
}
Как можно понять, ControlsEnabled блокирует контролсы на форме, чтобы пользователь ничего не натыкал, пока идет процесс. Проблема в том, что у клиента
очень часто, хоть и не всегда,
ControlsEnabled = true
не срабатывает. При этом видно, что
ResetDataToDefaults
срабатывает (поля на форме очищаются, хоть и остаются "отключенными").
_syncContext
я получаю в конструкторе вот так:
_syncContext = SynchronizationContext.Current
До того, как я начал использовать _syncContext, я использовал
Application.Current.Dispatcher.Invoke(delegate { ... })
В этом случае у меня иногда не работала смена статусов (их штук 10 меняется в процессе ожидания окончания работы
applicationWorker.DoTheThing
). Показывался первый статус (и изредка один из середины) и все. Когда поменял на
_syncContext
, все стало работать как часы.
Сейчас у меня локально все работает верно в 100% случаев, а у заказчика 4 раза из пяти проблема.
Я даже не знаю, в какую сторону копать.
Если это важно, класс
ApplicationWorker
находится в другой сборке
P.S. Только сейчас заметил, что
ResetDataToDefaults
выполняется
не в потоке UI. И, при этом, он срабатывает. Значит проблема в
_syncContext.Post
?