Поведение настройки ConfigureAwait и SynchronisationContext
-
21-12-2019 - |
Вопрос
В его ответ Стивен объяснил, что когда ConfigureAwait(false)
вызывается, остальная часть метода будет выполнена в потоке пула потоков если только Task
ты await
редактирование уже завершено.
Что ясно:Если я использую ConfigureAwait(false)
все, что выполняется после асинхронного вызова, будет выполнено в потоке пула потоков и, следовательно, не будет выполняться в UI SynchronizationContext, в противном случае (особенно это необходимо для таких вещей, основанных на пользовательском интерфейсе, как textBox1.Text = data.Property
) он запускается в рамках UI SynchronizationContext.
Чего я не понимаю, так это:Делает await
не означает, что Task
Я жду, когда это всегда завершено до того, как методы будут продолжены?Итак, как же задача может быть не выполнена до того, как она будет продолжена?
Решение
Представьте себе что-то вроде этого
var task = obj.SomeTaskAsync();
// do some lengthy computation
var value = await task.ConfigureAwait(false);
Я думаю, легко понять, что задача могла быть выполнена еще до того, как await task
вызов.
В этом случае код после ожидания будет выполнен в том же контексте, даже если вы использовали .ConfigureAwait(false)
.
Другие советы
Важно понимать порядок прецедентства.В частности, точечный оператор (.
) имеет более высокий приоритет, чем генеракодицетагкод.Итак, когда вы делаете:
await SomeMethodAsync().ConfigureAwait(false);
.
Это идентично:
var task = SomeMethodAsync();
var awaitable = task.ConfigureAwait(false);
await awaitable;
.
Итак, генеракодицетагкод оценивается перед выражением await
, который фактически делает (асинхронный) ждет.