Re[3]: Можно ли избавиться от async|await?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.12.25 07:48
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>Получается если не нужно ждать результата функции — пишем наоборот — nowait. Если ждать результат — ничего не пишем, по умолчанию.

G>>Так работает Go

S>Проверял или просто веришь?

Не проверял, но по косвенным признакам это так. Подробности ниже.


S>Вот C#


S>
S>async Task<int> SumAsync(int a, int b) {
S>    return a + b;
S>}

S>var x = await SumAsync(2, 3);
S>


Если что в этом коде func гарантированно выполнится в том же потоке, вернется промис aka Task, и await в вызывающем коде сразу же получит ризультат. Никакого асинхронного выполнения не будет.

S>Эквивалент в Go


S>
S>func sumAsync(a, b int) <-chan int {
S>    ch := make(chan int, 1)

S>    go func() {
S>        ch <- a + b
S>        close(ch)
S>    }()

S>    return ch
S>}

S>x := <-sumAsync(2, 3)
S>


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

Эквивалент на C# будет гораздо сложнее, там и Task.Run, и System.Threading.Channels.

Эквивалент в Go твоего примера на C# будет такой:

func sum(a, b int) int {
    return a+b;
}

x:=sum(2,3)


Функция также выполнится синхронно, также вызывающий код получит результат.


Самое интересное происходит когда внутри функции у тебя есть IO или другая операция, которая может выполниться в неблокирующем режиме
func read() ? {
   data, err := os.ReadFile("image.png")
   ...
}

x:=read()


На c# эквивалент будет такой
async Task<?> read() {
   var data = await System.IO.File.ReadAllBytesAsync("image.png")
   ...
}

x = await read();



Почему работает ровно то, что ты хотел получить — когда нужно ждать результата, то не пишем ничего. А если нужно не ждать, то вызываем функцию через оператор go.

Вызываются ли IO функции асинхронно я не проверял.
Но если запустить 1000 горутин и во всех них вызвать IO функции, то они будут выполняться параллельно, хотя потоков будет гораздо меньше. Это поведение я неоднократно наблюдал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.