Что такое класс Context класса SychronizationContext в C#? - PullRequest
0 голосов
/ 08 апреля 2020

Я новичок в C# многопоточности и следую некоторому руководству по многопоточности, асинхронному программированию и параллельному программированию, где я сталкивался с определенными терминами, такими как "Контекст", "переключение контекста" и "продолжение исходного контекста". ». Изучив документацию. NET, я обнаружил некоторые похожие классы и свойства в пространстве имен System.Threading, например «CurrentContext», который возвращает данные типа Context, и в пространстве имен System.Threading есть класс «SynchronizationContext».

Может ли кто-нибудь объяснить мне эти термины, свойства и классы? Мне трудно гр asp.

Спасибо.

1 Ответ

3 голосов
/ 08 апреля 2020

SynchronizationContext - это более старый API, предназначенный для обеспечения координации нескольких потоков друг с другом. В частности, это исторически происходит из мира пользовательского интерфейса, такого как winforms, где есть основной поток пользовательского интерфейса, и если у вас есть фоновая работа, может потребоваться вернуть обратно в поток пользовательского интерфейса, чтобы выполнять операции, такие как обновления пользовательского интерфейса. Для этого существует несколько механизмов, и SynchronizationContext является одним из них. По сути, это предоставляет два API: Post и Send (главное отличие состоит в том, что Send блокирует ожидание завершения работы).

Теперь, совершенно отдельно от этого, async / await - это другая модель API для выполнения асинхронного кода, т. Е.

var foo = await BarAsync();`
SomethingElse(foo);

Здесь, если BarAsync завершается синхронно, код просто продолжает нормально работать и SomethingElse выполняется немедленно; но если BarAsync возвращает неполное - то есть асинхронно - тогда поток раскручивается , возвращая управление туда, откуда он пришел, и продолжение подключается так, что будет запускать SomethingElse , когда станет доступен результат из BarAsync .

Если эти две модели пересекаются, это означает, что реализация await знает о существовании SynchronizationContext и , если он существует , он (по умолчанию) будет захватывать syn c -контекст, существовавший в то время, и возобновлять выполнение через этот syn c -context (Post) при основание того, что вы , вероятно, хотите вернуться в эту модель многопоточности, а не в модель потока того, что вызвало завершение BarAsync. Это поведение можно настроить (отключить) с помощью ConfigureAwait:

var foo = await BarAsync().ConfigureAwait(false);`
SomethingElse(foo);

Теперь оно будет , а не захватывать syn c -контекст, и когда незавершенная операция возобновляется, никаких дополнительных косвенность будет вызываться. Это полезно для избежания дополнительного переключения контекста, но означает, что некоторые вещи (например, обновление пользовательского интерфейса) могут потерпеть неудачу. Обычно (но не универсально) код приложения редко использует ConfigureAwait, а библиотека обычно использует ConfigureAwait.

...