Поработав некоторое время с асинхронным / ожидающим паттерном в C #, я внезапно осознал, что не знаю, как объяснить, что происходит в следующем коде:
async void MyThread()
{
while (!_quit)
{
await GetWorkAsync();
}
}
GetWorkAsync()
предполагается, что он возвращает ожидаемое, Task
что может вызвать или не вызвать переключение потока при выполнении продолжения.
Я не был бы смущен, если бы ожидание не было в петле. Естественно, я ожидаю, что остальная часть метода (то есть продолжение) будет потенциально выполняться в другом потоке, что нормально.
Однако внутри цикла концепция «остальной части метода» становится для меня немного туманной.
Что происходит с «остальной частью цикла», если поток включен в продолжение, если он не переключен? В каком потоке выполняется следующая итерация цикла?
Мои наблюдения показывают (не окончательно проверено), что каждая итерация начинается в том же потоке (исходном), а продолжение выполняется в другом. Это действительно может быть? Если да, то является ли это степенью неожиданного параллелизма, который необходимо учитывать для обеспечения безопасности потоков метода GetWorkAsync?
ОБНОВЛЕНИЕ: Мой вопрос не является дубликатом, как предлагают некоторые. while (!_quit) { ... }
Кодовый просто упрощение моего фактического кода. В действительности мой поток представляет собой долгоживущий цикл, который обрабатывает входную очередь рабочих элементов через регулярные промежутки времени (по умолчанию каждые 5 секунд). Фактическая проверка состояния выхода также является не простой проверкой поля, как предлагается в примере кода, а проверкой дескриптора события.