@Fly3110
web developer

Почему не обновляется View, когда обновляется property во viewmodel?

Внутри 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?
  • Вопрос задан
  • 79 просмотров
Пригласить эксперта
Ответы на вопрос 1
@soloveid
Возможно у Вас не воспроизводится потому, что у себя тестируете в Debug режиме,
а у пользователя наверное уже Release.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы