0

Если создать новый поток Thread thread = new Thread(Method) и запустить в нем выполнения метода Method через Start(), а в Main() продолжать что-то делать, то будет ли данный код синхронным многопоточным или асинхронным многопоточным, и как добиться асинхронной однопоточности если есть такая возможность

CrazyElf
  • 71,194
n_enrai49
  • 453

1 Answers1

2
  • Код является синхронным, когда его выполнение происходит непрерывно в одном контексте синхронизации в рамках текущего потока.
  • Код считается асинхронным, если выполнение кода прерывается для ожидания результата асинхронной операции, выполняемой в другом контексте. Фактически происходит выход из метода. Возврат к продолжению выполнения метода происходит повторным его вызовом с указанием другого состояния (см. шаблон проектирования "Конечный автомат").

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

Так что ваш вопрос непонятен, но я попробую пролить свет.

Возьму абстрактный термин "асинхронная однопоточность" и посчитаю это обращением к вопросу, может ли асинронный код метода между вызовами операций продолжать выполняться в том же потоке, в котором инициировано выполнение метода - ответ: может. Для этого потребуется однопоточный контекст синхронизации. Такой контекст можно найти в UI приложениях типа Winforms или WPF. Весь код, который изначально выполняется в приложении, выполняется в одном изначальном потоке - UI потоке. К этому потоку подключен UI контекст синхронизации для управления асинхронным кодом, то есть контекст активен по умолчанию.

async Task MethodAsync()
{
    // поток 1
    await Task.Delay(); // что там внутри - не важно, главное чтобы оно не завершиось синхронно
    // и здесь тоже поток 1
}

Если же запустить этот код из консольного приложения, где нет по умолчанию контекста синхронизации, то картина будет другая

async Task MethodAsync()
{
    // поток 1
    await Task.Delay();
    // а здесь уже поток 2
}

С механизмами работы самого контекста однопоточной синхронизации я игрался здесь.

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

var t1 = new Thread(Method);
t1.Start();
t1.Join(); // синхронное ожидание завершения другого потока

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

aepot
  • 49,560