ConfigureAwait (false) - всегда ли продолжение выполняется в другом потоке? - PullRequest
0 голосов
/ 24 ноября 2018

Этот вопрос задается в контексте ASP.NET WebApi 2 (не ASP.NET Core).Я попытался провести собственное исследование по этой теме, однако не смог найти однозначного ответа на этот вопрос.

Официальная документация MSDN для параметра метода ConfigureAwait(...) сообщает следующее:

true для попытки маршалинга продолжения обратно в исходный захваченный контекст;в противном случае false.

Стивен Туб дополнительно объясняет ключевое слово attempt следующим образом:

Это означает, что ничего не может бытьвернуться к ... может не быть контекста для захвата, например, SynchronizationContext.Current может вернуть null.

Если я правильно понимаю, тогда это не относится к ASP.NET WebApi 2, потому что присутствует AspNetSynchronizationContext, верно?

Теперь давайте рассмотрим следующий метод действия контроллера:

[HttpGet]
public async Task<String> GetValues()
{
    // First half.

    var values = await HeavyIo().ConfigureAwait(false);

    // Second half.

    return values;
}

Передав continueOnCapturedContext: false, гарантируется ли, чтопродолжение, помеченное как // Second half., получает всегда , выполненное в другом потоке?Или есть вероятность, что , если поток, в котором был захвачен контекст синхронизации, будет свободным после завершения асинхронной операции, , затем , продолжение будет запущено в том же потоке?

1 Ответ

0 голосов
/ 24 ноября 2018

Когда я спрашиваю в отрицательной форме, ответ такой, я думаю, довольно ясен - нет никакой гарантии, что вторая половина будет выполнена в потоке, отличном от первой.Как вы предполагаете, исходная нить вполне может быть удачной следующей доступной нитью, когда продолжение готово к выполнению.

Также важно отметить, что это context , не обязательно поток , который восстанавливается.В случае цикла сообщений Windows (например, потока пользовательского интерфейса WinForms) именно поток пользовательского интерфейса, выполняющий цикл сообщений, принимает и выполняет продолжение, следовательно, при ConfigureAwait(true) гарантируется тот же поток.Однако с другими объектами SynchronizationContexts не может быть особых причин требовать или даже предпочитать исходный поток, если все, что они считают «контекстом», восстанавливается;например, HttpContext.Current [, идентичность, культура] в ASP.NET.

Существует также, по крайней мере, теоретический шанс, что HeavyIo() завершится синхронно, в этом случае переключение контекста все равно не происходит, ивторая половина просто продолжится в той же теме, что и первая.Я могу только предположить из вашего выбора имен («тяжелый»), что вы намекаете, что это не вариант.

...