Объясните как работает await с CPU и IO bound операциями
Где и как будут выполнены методы DoCPUBoundOperation и DoIOBoundOperation? На сколько мне известно для IO Bound операций не нужны потоки и они выполняются в "пространстве ядра"(kernel space). В свою очередь CPU Bound операция выполняются "на CPU", поэтому требуют собственный поток. Опишите пожалуйста порядок как будет происходит процесс выполнения кода ниже.
static async Task Main(string[] args)
{
var cpuResult = await DoCPUBoundOperation();
var ioResult = await DoIOBoundOperation();
Console.WriteLine($"cpuResult = {cpuResult}, ioResult = {ioResult}");
Console.ReadKey();
}
public static async Task<string> DoIOBoundOperation()
{
var client = new WebClient();
var uri = new Uri("http://someAdress");
return await client.DownloadStringTaskAsync(uri);
}
public static Task<int> DoCPUBoundOperation()
{
var sum = 0;
for (int i = 0; i <= 10; i++)
{
sum += i;
}
Thread.Sleep(10000);
return Task.FromResult(sum);
}
Ряд вопросов которые нуждаются в отдельном внимании
- После попадания внутрь метода
DoIOBoundOperation, в каком потоке будет выполняться кусок кода
var client = new WebClient();
var uri = new Uri("http://someAdress");
В месте вызова
var ioResult = await DoIOBoundOperation();
для выполнения DoIOBoundOperation метода будет выделен отдельный поток? И если да, то поток возьмется из пула потоков?
Ответы (1 шт):
1)После поподания внутрь метода DoIOBoundOperation, в каком потоке будет выполняться кусок кода
В методе
public static async Task<string> DoIOBoundOperation()
{
var client = new WebClient();
var uri = new Uri("http://someAdress");
return await client.DownloadStringTaskAsync(uri);
}
Асинзронная только последняя операция. То есть всё, что до этой операции выполняется синхронно, как в обычном методе.
- В месте вызова var ioResult = await DoIOBoundOperation(); для выполнения DoIOBoundOperation метода будет выделен отдельный поток?И если да, то поток возьмется из пула потоков?
Асинхронный != многопоточный. Поток может быть создан, а может и нк быть создан. Для IO операций потоки не создаются, то есть для самой операции поток не нужен. Но вот рассмотрим следующий код
{код 1}
await IO operation
{код 2 - называется код-продолжение}
так вот код до асинхронной операции и код после асинзроннорй операции могут выполняться в одном и том же потоке или в разных потоках.
Например, если вы выполняете этот код в UI приложении в UI потоке, у которого есть контекст синхронизации, то обе части кода будут выполнены в одном потоке - в UI потоке.
Но в консольном приложении или если запустить этот код в потоке без контекста, то вторая часть может вернуться в поток, а может выполняиться в другом потоке из пула потоков.
Немного инфы тут.
Что касается DoCPUBoundOperation- то этот код не является асинхронным. Это обычный синхронный код.