Если создать новый поток Thread thread = new Thread(Method) и запустить в нем выполнения метода Method через Start(), а в Main() продолжать что-то делать, то будет ли данный код синхронным многопоточным или асинхронным многопоточным, и как добиться асинхронной однопоточности если есть такая возможность
-
2Проблема какая решается? – vitidev Apr 25 '22 at 21:45
-
Многопоточное vs асинхронное программирование – tym32167 Apr 25 '22 at 21:47
1 Answers
- Код является синхронным, когда его выполнение происходит непрерывно в одном контексте синхронизации в рамках текущего потока.
- Код считается асинхронным, если выполнение кода прерывается для ожидания результата асинхронной операции, выполняемой в другом контексте. Фактически происходит выход из метода. Возврат к продолжению выполнения метода происходит повторным его вызовом с указанием другого состояния (см. шаблон проектирования "Конечный автомат").
Для выполнения асинхронной операции может требоваться от 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 операций и обрабатывать их результаты по мере поступления, а не в порядке вызова. Синхронно такая фишка в лоб недоступна, придется писать всякие компенсирующие обвязки с какими-нибудь колбэками, что само по себе будет логически выглядеть как асинхронность, только на своих собственных костылях. :)
- 49,560
-
1
Синхронно ждать завершения нескольких операций вы не сможетеа как же WaitAny и другие? – Roman-Stop RU aggression in UA Apr 25 '22 at 22:28 -
1
-
@Roman-StopRUaggressioninUA sync-over-async это суррогат, про который в данном ответе речи не идёт. – aepot Apr 26 '22 at 07:23