Синхронизация Async/await — серебряная пуля на любой случай?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Синхронизация Async/await — серебряная пуля на любой случай?

Сообщение Anonymous »


Я думаю, что это одна из самых ужасных тем в async/await, возможно, только для C#, поскольку другие языки, похоже, не имеют таких ужасных ограничений. Об этой конкретной проблеме и о том, как с ней предположительно бороться, написано множество вопросов и блогов. Спустя много лет я до сих пор не знаю, как к этому подойти...
Проблема
С чем мы сталкиваемся довольно часто, так это с реализацией наших моделей представлений. Там у нас есть типичный RelayCommand, а с помощью сообщества Mvvm мы даже получаем AsyncRelayCommand. Ни один из них не позволяет использовать метод async CanExecute. Конструкторам этих типов требуется Func для аргумента canExecute.

В некоторых случаях нам необходимо вызвать асинхронный код из canExecute следующим образом

UpdateCommand = новый AsyncRelayCommand(Update, SomeCanExecuteMethod); ... ... частный bool SomeCanExecuteMethod() { вернуть _someDependency.DoSomethingAsync().Result; } Вопрос Теперь предположим, что мы сделали все так, как предполагалось при реализации DoSomethingAsync, и каждый вызов await правильно настроен с помощью ConfigureAwait(false). Может ли приведенная выше конструкция привести к тупику?
Альтернативный вариант
Предполагая, что ответ на вышеприведенный вопрос положительный, будет ли это всегда предотвращать потенциальную тупиковую ситуацию?

private bool SomeCanExecuteMethod() { вернуть Task.Run(async () => { return await _someDependency.DoSomethingAsync().ConfigureAwait(false); }).Результат; } Честно говоря, я не могу объяснить, почему это может решить проблему. Я кое-что помню (смутно), что это имеет своего рода побочный эффект: устанавливает для контекста синхронизации значение null, что, в свою очередь, предотвращает возникновение тупиковой ситуации.
Второй вариант
Поскольку альтернативный вариант (если он верен) немного напоминает «программирование с побочными эффектами», не лучше ли было бы указать явно и явно установить нулевой контекст синхронизации?
частный bool SomeCanExecuteMethod() { вар контекст = SynchronizationContext.Current; SynchronizationContext.SetSynchronizationContext(null); результат вар = _someDependency.DoSomethingAsync().Result; SynchronizationContext.SetSynchronizationContext(контекст); вернуть результат; }
ПРИМЕЧАНИЕ. Со смешением асинхронного и синхронного кода мы сталкиваемся чаще, чем только в этом примере MVVM. Нам также приходится иметь дело с наследием, которое в некоторых случаях просто слишком агрессивно, чтобы полностью выполнить рефакторинг для асинхронного ожидания. Поэтому мы ищем «серебряную пулю» для решения проблемы смешивания асинхронного и синхронного кода, если таковая имеется...
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»