Re[19]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 17:10
Оценка:
Здравствуйте, ·, Вы писали:

·>Самый вменяемый код — это на Java

Project Loom это конечно технически очень круто, но я не уверен, что .net надо подобное срочно пилить. Явная(async/await), а не скрытая, монада имеет свои преимущества.
Отредактировано 16.12.2025 17:13 novitk . Предыдущая версия .
Re[21]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 17:21
Оценка:
Здравствуйте, novitk, Вы писали:

T>>Делается тривиальный хелпер на три строчки и код будет выглядеть точно так же

N>И в результате имеем ровно тоже, что и в .net , но там в отличие от GoLang не забыли про ошибки и как и положено сделали каналы опциональными.

Нет, в .net совсем не тоже, коллега "." тут объяснил разницу: https://rsdn.org/forum/flame.comp/9033106.1
Автор: ·
Дата: 16.12 18:42


В моем примере
Автор: mrTwister
Дата: 16.12 18:51
func1() и func2() не принимали и не возвращали каналы, что не мешает написать
    val1 := RunTask(func1)
    val2 := RunTask(func2)
    println(val1.Get() + val2.Get())


при этом func1 и func2 — это самые обычные функции, не помеченные никакими async'ами и прочим мусором
лэт ми спик фром май харт
Отредактировано 16.12.2025 17:26 mrTwister . Предыдущая версия .
Re[22]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.12.25 17:29
Оценка:
Здравствуйте, mrTwister, Вы писали:

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


T>>>Делается тривиальный хелпер на три строчки и код будет выглядеть точно так же

N>>И в результате имеем ровно тоже, что и в .net , но там в отличие от GoLang не забыли про ошибки и как и положено сделали каналы опциональными.

T>Нет, в .net совсем не тоже, коллега "." тут объяснил разницу: https://rsdn.org/forum/flame.comp/9033106.1
Автор: ·
Дата: 16.12 18:42


T>В моем примере
Автор: mrTwister
Дата: 16.12 18:51
func1() и func2() не принимали и не возвращали каналы, что не мешает написать

T>
T>    val1 := RunTask(func1)
T>    val2 := RunTask(func2)
T>    println(val1.Get() + val2.Get())
T>


T>при этом func1 и func2 — это самые обычные функции, не помеченные никакими async'ами и прочим мусором


И чем это лучше

val1 := Task.Run(func1)
val2 := Task.Run(func2)
await Task.WhwnAll(val1, val2);
println(val1.Result + val2.Result)
и солнце б утром не вставало, когда бы не было меня
Re[22]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 17:33
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Нет, в .net совсем не тоже, коллега "." тут объяснил разницу: https://rsdn.org/forum/flame.comp/9033106.1
Автор: ·
Дата: 16.12 18:42

Там о том, что Serginio1 влез не по делу с Task.WhenAll.

T>при этом func1 и func2 — это самые обычные функции, не помеченные никакими async'ами и прочим мусором

Будь они обычные, как в Project Loom, тебе бы RunTask, aka Task.Run, не понадобился. Там семантика результата функций поддерживается в обеих контекстах, а в GoLang только в синхронном.
Re[22]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 17:58
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Ну и чем это лучше

S>Task.WhenAll
а) WhenAll тут не нужен.
б) Суть в другом. В jvm nет никаких async функций. Любая функция может быть запущена, как синхронно, так и ассинхронно. Решение принимает тот, кто ее вызывает. Сейчас прибежит mrTwister и скажет, что в GoLang тоже. И отчасти он будет прав, но лишь отчасти. Из за криворукости "простоты" там не поддерживается вся семантика в обеих контестах. В частности, если функция вызвана через go, то ее результат получить невозможно. Единственный способ получения результата из ассинхронного вызова это использовать всякие неявные методы (обычно каналы, ну или shared memory), но это требует переписки функций, то есть фактически не сильно отличается от .net.
Re[18]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 18:04
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>То есть функция начала работать на одном потоке ОС, а закончила на другом потоке. Как это возможно, если бы она не была асинхронной?

T>Параллельно я запустил еще десяток горутин без функции Foo, чтобы переезд на тругой тред чаще воспроизводился. Оно воспроизводится и без этого, но не каждый раз, надо просто чаще позапускать (иногда раз 10): https://go.dev/play/p/087bV3w7fMT

Ну вот теперь — верю. Но тут отсутствует возможность получить Promise/Future/Task. Т.е. заготовку под ответ, которую можно куда-то добавить, что-то с ней сделать. Это не удобно.
=сначала спроси у GPT=
Re[23]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 18:04
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Ну и чем это лучше

S>Task.WhenAll
а) WhenAll тут не нужен.
б) Суть в другом. В jvm nет никаких async функций. Любая функция может быть запущена, как синхронно, так и ассинхронно(виртуальные потоки, ака "зеленые"). Решение принимает тот, кто ее вызывает, a не тот кто пишет . При этом, если она запущена на "зеленых", то блокировать OS поток она не будет, даже если там бесконечный цикл и без всяких дотнетовских Task.Yield(). Сейчас прибежит mrTwister и скажет, что в GoLang то же. И отчасти он будет прав, но лишь отчасти. Из за криворукости "простоты" там не поддерживается вся семантика в обеих контестах. В частности, если функция вызвана через go, то ее результат получить невозможно. Единственный способ получения результата из ассинхронного вызова это использовать всякие неявные методы (обычно каналы, ну можно и shared memory), но это требует переписки функций, то есть фактически не сильно отличается от .net.
Отредактировано 16.12.2025 18:13 novitk . Предыдущая версия . Еще …
Отредактировано 16.12.2025 18:11 novitk . Предыдущая версия .
Re[6]: Можно ли избавиться от async|await?
От: SkyDance Земля  
Дата: 16.12.25 18:11
Оценка:
T>Дальше не читал. Горутина в go — это просто структура данных. Как, например, Task в .net.

Ага.
Собственно, Erlang тем и отличается, что у них process не просто структура данных, а еще и всякие поля для scheduling'а, и структура эта определена в виртуальной машине, а не просто как часть user-space library.
Re[21]: Можно ли избавиться от async|await?
От: SkyDance Земля  
Дата: 16.12.25 18:13
Оценка:
·>Это же полная Ж по сравнению с java.

Это просто означает, что вся "асинхронщина" сидит в user space, а не в виртуальной машине.
Re[20]: Можно ли избавиться от async|await?
От: SkyDance Земля  
Дата: 16.12.25 18:15
Оценка: :)
N>Project Loom это конечно технически очень круто, но я не уверен, что .net надо подобное срочно пилить.

Надо, конечно, и в M$ это тоже понимают, просто это совсем не так легко, как кажется. Сделать Erlang из Java/C# занимает годы.
Re[23]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.12.25 18:20
Оценка:
Здравствуйте, novitk, Вы писали:


S>>Ну и чем это лучше

S>>Task.WhenAll

N>а) WhenAll тут не нужен.


Нужен. Он хочет параллельно выполнять 2 задачи. Хотя в .Net есть еще и Parallel.
N>б) Суть в другом. В jvm nет никаких async функций. Любая функция может быть запущена, как синхронно, так и ассинхронно. Решение принимает тот, кто ее вызывает. Сейчас прибежит mrTwister и скажет, что в GoLang тоже. И отчасти он будет прав, но лишь отчасти. Из за криворукости "простоты" там не поддерживается вся семантика в обеих контестах. В частности, если функция вызвана через go, то ее результат получить невозможно. Единственный способ получения результата из ассинхронного вызова это использовать всякие неявные методы (обычно каналы, ну или shared memory), но это требует переписки функций, то есть фактически не сильно отличается от .net.

Ну async/await сделан на основе Linq вернее yield в IEnumerable. Тут рядом ветка C++ http://rsdn.org/forum/cpp/9027202.flat
Автор: Videoman
Дата: 06.12 00:32


Они тоже мучаются с корутинами. В .Net же Linq компилятор генерирует класс с автоматом.

Компилятор C# действительно генерирует скрытый класс-автомат (State Machine) для LINQ-выражений (особенно для тех, что используют yield return и foreach), который хранит состояние и разбивает выполнение метода на секции, что позволяет ему «замораживать» и «возобновлять» выполнение, подобно работе async/await, с ключевыми вызовами, такими как MoveNext() для перехода к следующему элементу, создавая эффективные итераторы и асинхронные потоки.


В этом и вся прелесть .Net. Если сначала Linq тормозил, то затем его оптимизировали. Это же касается и async/await
и солнце б утром не вставало, когда бы не было меня
Re[20]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 16.12.25 18:25
Оценка: +1
Здравствуйте, novitk, Вы писали:

N>·>Самый вменяемый код — это на Java

N>Project Loom это конечно технически очень круто, но я не уверен, что .net надо подобное срочно пилить. Явная(async/await), а не скрытая, монада имеет свои преимущества.
Так CompletableFuture вроде есть, работает так же монадно, и не важно виртуальные треды или платформенные.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[21]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 18:27
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Project Loom это конечно технически очень круто, но я не уверен, что .net надо подобное срочно пилить.

SD>Надо, конечно, и в M$ это тоже понимают, просто это совсем не так легко, как кажется. Сделать Erlang из Java/C# занимает годы.
https://github.com/dotnet/runtimelab/issues/2398

This issue is still useful as a summary of the experiment, but current efforts are now focused on Runtime-Async, so I'm going to close this issue and people can look at dotnet/runtime#109632 instead.

Re[6]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 18:43
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Дальше не читал. Горутина в go — это просто структура данных. Как, например, Task в .net. Не в смысле, что это аналог, в смысле что это вспомогательная структура данных для организации вычислений. Вызов функции в go блокирует горутину точно так же, как await блокирует асинхронную функцию в C#


Если бы была возможность получить Task|Promise|Future не дожидаясь выполнения — то цены бы не было. А так все похерили — просто go не дает доступа к промису
=сначала спроси у GPT=
Re[24]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 18:43
Оценка:
Здравствуйте, Serginio1, Вы писали:

N>>а) WhenAll тут не нужен.

S>Нужен. Он хочет параллельно выполнять 2 задачи. Хотя в .Net есть еще и Parallel.
Просто прогони код с двумя await и свой и убедись, что результат одинаков. await, как раз тот сахар, который тут доктор прописал. WhenAll нужен когда число Task не определенно.

S> Ну async/await сделан на основе Linq вернее yield в IEnumerable.

Я понимаю, что ты очень хочешь поделиться своими познаниями, но мы обзуждали разницу с jvm, а не на чьей основе он сделан.

S> В этом и вся прелесть .Net. Если сначала Linq тормозил, то затем его оптимизировали. Это же касается и async/await

Его некуда оптимизировать компилятором. Для реальных "green thread" нужно менять рантайм.
Re[25]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.12.25 19:34
Оценка: -1 :)
Здравствуйте, novitk, Вы писали:


N>>>а) WhenAll тут не нужен.

S>>Нужен. Он хочет параллельно выполнять 2 задачи. Хотя в .Net есть еще и Parallel.
N>Просто прогони код с двумя await и свой и убедись, что результат одинаков. await, как раз тот сахар, который тут доктор прописал. WhenAll нужен когда число Task не определенно.
Согласен. Если сначала запустить 2 задачи а затем вызвать await будет одно и тоже.
WhenAll , что бы сократить код. Результат можно получить в цикле или нужно просто дождаться выполнение всех задач.

S>> Ну async/await сделан на основе Linq вернее yield в IEnumerable.

N>Я понимаю, что ты очень хочешь поделиться своими познаниями, но мы обзуждали разницу с jvm, а не на чьей основе он сделан.
Эти зеленые потоки уже обсуждали множество раз. Там единственный плюс, что все выполняется в одном потоке, поэтому не нужны блокировки.
То же можно сделать и на C# со своим шедулером с одним потоком.

S>> В этом и вся прелесть .Net. Если сначала Linq тормозил, то затем его оптимизировали. Это же касается и async/await

N>Его некуда оптимизировать компилятором. Для реальных "green thread" нужно менять рантайм.
Ну появились ValueTask, оптимизируются и шедулеры, оптимизируется и автомат переходов.
А green thread это вообще хрень.

В современных версиях Java, таких как Java 8 и выше, зелёные потоки не используются по умолчанию, и управление потоками передаётся операционной системе.

и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.12.2025 19:42 Serginio1 . Предыдущая версия . Еще …
Отредактировано 16.12.2025 19:40 Serginio1 . Предыдущая версия .
Re[7]: Можно ли избавиться от async|await?
От: dsorokin Россия  
Дата: 16.12.25 19:46
Оценка: +1
Здравствуйте, Shmj, Вы писали:

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


T>>Дальше не читал. Горутина в go — это просто структура данных. Как, например, Task в .net. Не в смысле, что это аналог, в смысле что это вспомогательная структура данных для организации вычислений. Вызов функции в go блокирует горутину точно так же, как await блокирует асинхронную функцию в C#


S>Если бы была возможность получить Task|Promise|Future не дожидаясь выполнения — то цены бы не было. А так все похерили — просто go не дает доступа к промису


Ты чего удумал? Библиотеку комбинаторов создать на голанге? Гоферы не поймут!

Кстати, а как у тебя с хаскелем дела продвигаются? Не смотрел?

Эрланг, голанг и хаскель объединяет то, что во всех трех языках есть зеленые потоки (или их аналоги под другим маркетинговым брендом). Вот, когда есть такие потоки, то тогда разумно делать IO асинхронным внутри рантайма, причем с точки зрения программиста это становится прозрачным. Код IO программистом пишется как якобы синхронный, но исполняется он тогда как асинхронный на самом деле

Кстати, в хаскеле можно запустить асинхронное вычисление и получить аналог "Task|Promise|Future". В пакете async есть даже целый набор комбинаторов для этого. Более того, там даже есть такая штука, как асинхронные исключения, что как раз позволяет реализовать интересные комбинаторы с этими самыми "Task|Promise|Future". Например, можно запустить парочку другую асинхронных вычислений, дождаться первого завершивсегося, а остальные вычисления прибить за ненадобностью через такие исключения

Асинхронные исключения не пошли в серию, то есть, не пошли в мейнстрим, как не пошли рестарты в свое время из коммон-лиспа, но кое-что интересное с этими асинхронными исключениями получить можно (как и геморрой при обработке критических секций тоже)
Re[26]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 16.12.25 19:47
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Эти зеленые потоки уже обсуждали множество раз. Там единственный плюс, что все выплняется в одном потоке, поэтому не нужна синхронизация.

зеленые потоки не выполняются в одном OS потоке и синхронизация нужна.

S>То же можно сделать и на C# со своим шедулером с одним потоком.

Бесшовно нельзя. Именно поэтому есть в C# Thread.Sleep и Таsk.Sleep, a в Го и jvm одна. Именно поэтому надо руками добавлять Task.Yield в числодробилки, а на Gо и jvm нет.

S>

S>В современных версиях Java, таких как Java 8 и выше, зелёные потоки не используются по умолчанию, и управление потоками передаётся операционной системе.

Что такое "по умолчанию"?
Re[27]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 16.12.25 20:16
Оценка:
Здравствуйте, novitk, Вы писали:

S>>

S>>В современных версиях Java, таких как Java 8 и выше, зелёные потоки не используются по умолчанию, и управление потоками передаётся операционной системе.

N>Что такое "по умолчанию"?
Чувак совершенно не в теме и порет чушь. Откуда-то выкопал цитату о "современных" версиях 25-летней давности про зелёные потоки, которые deprecated с версии 1.3. А тут идёт речь о Project Loom — это виртуальные потоки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[20]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 16.12.25 20:23
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>>>То есть функция начала работать на одном потоке ОС, а закончила на другом потоке. Как это возможно, если бы она не была асинхронной?

T>·>Простите, но это уличная магия, а не асинхронность. Так работает шедулер и переключение контекста. После thread park (то что делает sleep) шедулер может продолжить исполнение на другом ядре. Это многопоточность, а не асинхронность.
T>Шедулер может продолжить выполнение на другом ядре, а на другом потоке не может. Тут же выполнение происходит на другом потоке, а не ядре. Чтобы шедулер такое сделал функция обязана быть асинхронной и предоставлять промис для продолжения
Ты имеешь в виду шедулер ОС, а я имел в виду шедулер в рантайме Go. Обычная многопоточка, никакой асинхронности.

T>·>Асинхронный это если части кода выполняются одновременно. Примерно так, код, ясен пень, неработающий:

T>Делается тривиальный хелпер на три строчки и код будет выглядеть точно так же
Ну т.е. создать новую функцию и передать всё через одно место (chan). И ещё каким-то хитровывернутым синтаксисом...
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 16.12.2025 20:24 · . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.