Контекст синхронизации - PullRequest
0 голосов
/ 04 марта 2019

Я понимаю, .ConfigureAwait(false) означает, что продолжение не обязательно должно быть в том же потоке, что и при вводе.

Поэтому мне интересно, какой контекст синхронизации я получу обратно в someUIButton_click.

static async void someUIButton_click()
{
   await T1();
   // Am I sur to be on the UI thread ?
}

static async Task T1() => await doSomethingAsync().ConfigureAwait(false)

Контекст: C #, winforms, .Net 4.7

1 Ответ

0 голосов
/ 04 марта 2019

SynchronizationContext и контекст выполнения

Каждый поток имеет связанный с ним контекст, он также известен как Текущий контекст , и эти контексты могут быть общими для всех потоков.ExecutionContext содержит соответствующие метаданные текущей среды или контекста, в котором выполняется программа.

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

  • Winform Apps - WindowsFormsSynchronizationContext
  • WPF APS - DispatcherSynchronizationContext
  • Значение по умолчанию SynchronizationContext - по умолчанию (ThreadPool) SynchronizationContext
  • ASP.Net - AspNetSynchronizationContext

Как await использует SynchronisationContext's

Async / await - просто волшебство компилятора, чтобы упростить создание асинхронных вещей (он не заставляет ваш код работать асинхронно), все, что он делает, когда видит await, разбивает ваш метод на конечный автомат и когда вещь, которую вы ожидаете , завершает выполнение, конечный автомат возобновляется, и ваш код продолжает работать.Возобновление выполнения называется продолжением .

Особенность ключевого слова await заключается в том, что он захватывает текущий SynchronizationContext перед выполнением асинхронной операции, а затем отправляет продолжение к этому SynchronizationContext, что означает, что если вы находитесь в потоке пользовательского интерфейса когда вы await, после того как он завершится, то ваш код продолжит выполнение в потоке пользовательского интерфейса (который называется Выгрузка )

ConfigureAwait ()

Все ConfigureAwait(false) делает, настраивает задачу так, чтобы продолжение после await не нужно запускать в контексте вызывающей стороны.Это может иметь несколько преимуществ, одним из которых является небольшой выигрыш в производительности и более спорная остановка взаимоблокировок в определенных ситуациях.

Ответ

Каждый раз, когда вы вызываете await, создается State Machine , чтобы сотворить чудеса Async Await Pattern и установить продолжение .

Только потому, что для ConfigureAwait установлено значение false вложенный в другой await ( конечный автомат ) не изменяет исходный вызов, который настроен на продолжение вызова Контекст синхронизации (если применимо).

Примечание: : someUIButton_click запущено незамеченным, и у вас должна быть соответствующая проверка ошибок

Обновление

Так что это означает, что ямогу делать все, что захочу, в T1, пока он не взаимодействует с некоторыми компонентами пользовательского интерфейса

Вы "на первый взгляд" имеете свободный доступ к компонентам пользовательского интерфейса из someUIButton_click иT1 однако, за исключением того, что после await в T1 вы настроили задачу так, чтобы продолжению не нужно было возвращаться в вызывающий контекст.Доступ к компоненту UI здесь, вероятно, вызовет у вас проблемы.

Так что же после await in someUIButton_click?

Что ж, в этом случае задача имеет (по умолчанию)захватил текущий контекст (предположительно, ваш поток пользовательского интерфейса ), и продолжение будет продолжено в этом контексте.Каждое вложенное ожидание - это отдельный случай, и вызывающий await (конечный автомат) выбирает, в каком контексте он продолжает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...