Вариант 1 - отсутствие чего либо асинхронного
async Task Main()
{
var tasks = Enumerable.Range(0, 10).Select(x=>AsyncMethod()).ToList();
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.WhenAll(tasks);
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
}
async Task AsyncMethod()
{
Console.WriteLine($"started in thread {Thread.CurrentThread.ManagedThreadId}");
var ret = await Task.FromResult(10);
Console.WriteLine($"finished in thread {Thread.CurrentThread.ManagedThreadId}");
}
В выводе все потоки одинаковые
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
started in thread 12
finished in thread 12
main in thread 12
main in thread 12
Вариант 2 - какая то асинхронная задача
async Task Main()
{
var tasks = Enumerable.Range(0, 10).Select(x=>AsyncMethod()).ToList();
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.WhenAll(tasks);
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
}
async Task AsyncMethod()
{
Console.WriteLine($"started in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.Delay(1000);
Console.WriteLine($"finished in thread {Thread.CurrentThread.ManagedThreadId}");
}
В выводе выполнение прыгает по потокам, можно думать о какой то многопоточности
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
main in thread 12
finished in thread 14
finished in thread 8
finished in thread 11
finished in thread 11
finished in thread 11
finished in thread 11
finished in thread 8
finished in thread 9
finished in thread 14
finished in thread 10
main in thread 10
Вариант 3 - какая то асинхронная задача + контекст синхронизации WPF
async Task Main()
{
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
var tasks = Enumerable.Range(0, 10).Select(x=>AsyncMethod()).ToList();
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.WhenAll(tasks);
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
}
async Task AsyncMethod()
{
Console.WriteLine($"started in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.Delay(1000);
Console.WriteLine($"finished in thread {Thread.CurrentThread.ManagedThreadId}");
}
И мы снова в одном потоке
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
main in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
finished in thread 12
main in thread 12
Вариант 3 - какая то асинхронная задача + контекст синхронизации WPF + ConfigureAwait(false)
async Task Main()
{
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
var tasks = Enumerable.Range(0, 10).Select(x=>AsyncMethod()).ToList();
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.WhenAll(tasks);
Console.WriteLine($"main in thread {Thread.CurrentThread.ManagedThreadId}");
}
async Task AsyncMethod()
{
Console.WriteLine($"started in thread {Thread.CurrentThread.ManagedThreadId}");
await Task.Delay(1000).ConfigureAwait(false);
Console.WriteLine($"finished in thread {Thread.CurrentThread.ManagedThreadId}");
}
И снова несколько потоков
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
started in thread 12
main in thread 12
finished in thread 6
finished in thread 18
finished in thread 6
finished in thread 6
finished in thread 6
finished in thread 6
finished in thread 6
finished in thread 6
finished in thread 14
finished in thread 18
main in thread 12
Таким образом, наличие асинхронного метода не говорит ничего о том, будет ли асинхронный вызов вообще и будет ли использована многопоточность.
awaitпередTask? И, кажется,IDEв таком случае сам предлагаетasyncверсию лямбды писать. Но могу и путать. – CrazyElf Dec 15 '20 at 13:09select, там нужно уже было результат работы функций по полям распихивать – CrazyElf Dec 15 '20 at 13:18AsyncMethodвнутри себя будет делатьawait, то другие таски смогут получить управление, покаawaitждёт, а так да, параллельность тут не гарантирована. – CrazyElf Dec 15 '20 at 13:19TaskScheduler, то разработчик наверное должен наверняка знать, как именно у него отработает вся эта асинхронная история, а не задавать вопросы типа того что выше. Поэтому предположу, что там всё дефолтное. – aepot Dec 15 '20 at 14:03