Здравствуйте, 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 функции, то они будут выполняться параллельно, хотя потоков будет гораздо меньше. Это поведение я неоднократно наблюдал.