Re[38]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 20.12.25 10:33
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>·>Было мало кода, был простой код. Стало много сложного кода. Что ты хотел мне этим продемострировать?

S>>>Угу был дермовый код с блокировками потоков и хранением переменных привязанных к потоку.
S>·>Что в этом плохого?
S> Ты серьезно? Проблема серверов в переключении потоков, на это тратится время.
Хорошо, но уже лучше.
Т.е. на самом деле-то не сам код дерьмо, а дерьмо в переключении потоков, на которое тратится время.

S>При использовании задач используется пул потоков, а задача представляет собой замыкание с автоматом переходов после выполнения задачи.

Вот и представь себе, что существуют такие потоки, на переключение которых не тратится время! Код перестанет быть дерьмовым с твоей точки зрения?

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

S>·>Чем это лучше?
S> Ну во первых lock используется только внутри одного потока, при использовании асинхронного подхода нужно использовать SemaphoreSlim.
Ты, видимо, на какой-то другой вопрос ответил. Я спросил, чем лучше, а не где что нужно унутре использовать. Для меня как-то не очевидно, что нужда чего-то где-то делать является чем-то хорошим...
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[39]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.12.25 11:57
Оценка:
Здравствуйте, ·, Вы писали:

S>>При использовании задач используется пул потоков, а задача представляет собой замыкание с автоматом переходов после выполнения задачи.

·>Вот и представь себе, что существуют такие потоки, на переключение которых не тратится время! Код перестанет быть дерьмовым с твоей точки зрения?
Виртуальные потоки это примитивный аналог задач.

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

S>>·>Чем это лучше?
S>> Ну во первых lock используется только внутри одного потока, при использовании асинхронного подхода нужно использовать SemaphoreSlim.
·>Ты, видимо, на какой-то другой вопрос ответил. Я спросил, чем лучше, а не где что нужно унутре использовать. Для меня как-то не очевидно, что нужда чего-то где-то делать является чем-то хорошим...

Еще раз ответь себе на вопросы про Task.WhenAll, Task.WhenAny, CancellationToken
И как ты аналог TaskCompletionSource (CompletableFuture) будешь использовать в виртуальных потоках.

Так у задач есть свойство IsCompleted. Например Task.FromResult возвращает результат и задача не прерывается.

Еще раз виртуальные потоки хороши для старого кода, а вот для нового кода с async/await c Task.WhenAll, Task.WhenAny, CancellationToken, TaskCompletionSource
дает больше возможностей.

Это как претензии к Delphi насчет begin end. В студии есть подсказка и написать await не проблема за то дает больше степеней свободы.

Много примеров ты найдешь здесь
Использование асинхронного шаблона на основе задач
и солнце б утром не вставало, когда бы не было меня
Re[40]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 20.12.25 14:59
Оценка: +3 :)
Здравствуйте, Serginio1, Вы писали:

S>·>Вот и представь себе, что существуют такие потоки, на переключение которых не тратится время! Код перестанет быть дерьмовым с твоей точки зрения?

S> Виртуальные потоки это примитивный аналог задач.
В точности наоборот. Задачи — примитивный кривой костыль при отсутствии возможности использовать потоки без проблем с производительностью. Ты же это сам кодом продемонстрировал.

S>>>·>Чем это лучше?

S>>> Ну во первых lock используется только внутри одного потока, при использовании асинхронного подхода нужно использовать SemaphoreSlim.
S>·>Ты, видимо, на какой-то другой вопрос ответил. Я спросил, чем лучше, а не где что нужно унутре использовать. Для меня как-то не очевидно, что нужда чего-то где-то делать является чем-то хорошим...
S> Еще раз ответь себе на вопросы про Task.WhenAll, Task.WhenAny,
CompletableFuture.allOf и CompletableFuture.anyOf

S> CancellationToken

thread.interrupt() или CompletableFuture.cancel. При этом не надо этот твой мусор везде таскать через параметры.

S>И как ты аналог TaskCompletionSource (CompletableFuture) будешь использовать в виртуальных потоках.

Ровно так же, как и в обычных. В этом и сила.

S>Так у задач есть свойство IsCompleted.

Future.isDone

S>Например Task.FromResult возвращает результат и задача не прерывается.

CompletableFuture.completedFuture

S> Еще раз виртуальные потоки хороши для старого кода, а вот

Они хороши для любого кода. Ты же сам это продемонстировал.

S>для нового кода с async/await c Task.WhenAll, Task.WhenAny, CancellationToken, TaskCompletionSource дает больше возможностей.

Как оказалось — не даёт.

S>Это как претензии к Delphi насчет begin end. В студии есть подсказка и написать await не проблема за то дает больше степеней свободы.

Ты просто в суть вникнуть не можешь, т.к. проблемы с чтением. Вот про CompletableFuture упомянул, но, очевидно, даже доку не открывал. Иначе бы не писал этот бред.

S>Много примеров ты найдешь здесь

S>Использование асинхронного шаблона на основе задач
Зачем мне этот цирк... Мне работу работать надо, а не через обручи прыгать.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[41]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.12.25 13:37
Оценка:
Здравствуйте, ·, Вы писали:

Вот смотрю я на асинхронное программирование в Яве

Асинхронные задачи FutureTask. Callable и Future

import java.util.concurrent.*;
 
class Program{
 
    public static void main(String[] args) {
          
        System.out.println("Main thread started...");
 
        int number = 5;  // исходное число для вычисления факториала
 
        // определяем задачу, которая вычисляет факториал
        Callable<Integer> task = () -> {
 
            int n = number;     // копируем число, чтобы не изменять его
            int result = 1;
            while(n > 0) result *= n--;
            return result;  // возвращаем результат задачи
        };
 
        // определяем задачу, которая будет выполнена в будущем
        var futureTask = new FutureTask<Integer>(task);
        // создаем и запускаем поток
        var t = new Thread(futureTask); // futureTask - это объект Runnable
        t.start();
 
        // здесь могут быть какие-либо другие операции метода main
        // которые должны выполняться одновременно с futureTask
        System.out.println("Main thread works...");
 
        try{
            // ожидаем выполнения задачи
            Integer factorial = futureTask.get();
            System.out.printf("factorial of %d is %d\n", number, factorial);
        }
        catch(Exception ex){ 
            System.out.println(ex.getMessage()); 
        }
 
        System.out.println("Main thread finished...");
    }
}


Или

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(task);
 
        // передаем в thenAccept обратный вызов
        future.thenAccept(result -> System.out.printf("factorial of %d is %d\n", number, result));
 
        // future.thenAccept - не блокирует основной поток 
        // и одновременно мы можем выполнять в основном потоке некоторую работу 
        System.out.println("Main thread works...");
  
        Thread.sleep(2000);
 
        System.out.println("Main thread finished...");


На C# будет типа такого

Task<int> task= Task.Run(()=>
 {
 
            int n = number;     // копируем число, чтобы не изменять его
            int result = 1;
            while(n > 0) result *= n--;
            return result;  // возвращаем результат задачи
        };

 // здесь могут быть какие-либо другие операции метода main
 // которые должны выполняться одновременно с futureTask

  try{
var res = await task; // или в синхронном варианте  int res = task.Result;
 }
        catch(Exception ex){ 
            Console.WriteLine(ex.ToString()); 
        }

)


В JavaScript, под влиянием TypeScript пришли к тому, что await значительно лучше чем создание цепочек обратных вызовов

CompletableFuture и промисы. Обработка результата асинхронных задач
и солнце б утром не вставало, когда бы не было меня
Отредактировано 21.12.2025 14:09 Serginio1 . Предыдущая версия . Еще …
Отредактировано 21.12.2025 14:06 Serginio1 . Предыдущая версия .
Отредактировано 21.12.2025 13:48 Serginio1 . Предыдущая версия .
Re[42]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 05.01.26 10:03
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Вот смотрю я на асинхронное программирование в Яве

Похвально. Ещё посмотри на Structured Concurrency

S> // передаем в thenAccept обратный вызов

Непонятно какое это отношение имеет к virtual threads и к сабжу.

S> В JavaScript, под влиянием TypeScript пришли к тому, что await значительно лучше чем создание цепочек обратных вызовов

Лучше, конечно. Но речь идёт про virtual threads. С ними не нужен ни await, ни цепочки обратных вызовов. Можно писать тупой синхронный код и выполнять на миллионах тредов.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 05.01.2026 13:05 · . Предыдущая версия .
Re[10]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 05.01.26 10:09
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>>>Можешь не отвечать. А, вот тебе ещё в догонку: сможешь сделать так, чтоб при указанных нагрузках не всё процессорное время сожрал GC?

Ф>·>А причём тут сабж?
Ф>Чем больше потоков — тем больше рутов, от которых пляшет GC.
Да, кстати. Подумалось... async создаёт task-объект со state machine на каждый вложенный вызов. А стеки в VT это просто ноды в куче для GC. И это просто стек вызовов, а не дополнительный объект со стейт-машиной. Т.е. теоретически это более эффективно с т.з. GC. Но замеры я не проводил, может разница и незначительна.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: Можно ли избавиться от async|await?
От: novitk США  
Дата: 05.01.26 22:16
Оценка:
Здравствуйте, ·, Вы писали:

Ф>>Чем больше потоков — тем больше рутов, от которых пляшет GC.

·>Да, кстати. Подумалось... async создаёт task-объект со state machine на каждый вложенный вызов. А стеки в VT это просто ноды в куче для GC. И это просто стек вызовов, а не дополнительный объект со стейт-машиной. Т.е. теоретически это более эффективно с т.з. GC. Но замеры я не проводил, может разница и незначительна.

Чем обьект стек, отличается от обьекта стейт-машина с точки зрения GC?
Другое дело что "тем больше рутов, от которых пляшет GC" совершенно не расскрыто. Может и не больше. А может и больше, но это не значит, что оно медленней.
Re[12]: Можно ли избавиться от async|await?
От: SkyDance Земля  
Дата: 05.01.26 22:36
Оценка:
N>Чем обьект стек, отличается от обьекта стейт-машина с точки зрения GC?

Напомнило вот это: "исключения плохие, потому что медленные, поэтому вместо исключений мы будем использовать кортеж Result, в поле Error которого мы будем на каждом уровне добавлять информацию о месте пролета ошибки".
Re[12]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 06.01.26 10:36
Оценка:
Здравствуйте, novitk, Вы писали:

N>·>Да, кстати. Подумалось... async создаёт task-объект со state machine на каждый вложенный вызов. А стеки в VT это просто ноды в куче для GC. И это просто стек вызовов, а не дополнительный объект со стейт-машиной. Т.е. теоретически это более эффективно с т.з. GC. Но замеры я не проводил, может разница и незначительна.

N>Чем обьект стек, отличается от обьекта стейт-машина с точки зрения GC?
Стек выделяется чанками. Т.е. объектов будет гораздо меньше, даже для глубоких рекурсий. Вот правда рекурсия на async мне бы мозг сломала... как вообще такое отлаживать например...
Если я правильно понял, то размер чанков выбирается автомагически в зависимости от того как операции ввода-вывода расположены в коде и согласовано с работой GC.
https://youtu.be/6nRS6UiN7X0

N>Другое дело что "тем больше рутов, от которых пляшет GC" совершенно не расскрыто. Может и не больше. А может и больше, но это не значит, что оно медленней.

Ну нету рутов в виртуальных потоках. Из jep 444: "Unlike platform thread stacks, virtual thread stacks are not GC roots. Thus the references they contain are not traversed in a stop-the-world pause by garbage collectors, such as G1, that perform concurrent heap scanning."
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[13]: Можно ли избавиться от async|await?
От: НепредставимыйПхы КНДР  
Дата: 06.01.26 13:15
Оценка:
Здравствуйте, ·, Вы писали:

N>>Другое дело что "тем больше рутов, от которых пляшет GC" совершенно не расскрыто. Может и не больше. А может и больше, но это не значит, что оно медленней.

·>Ну нету рутов в виртуальных потоках. Из jep 444: "Unlike platform thread stacks, virtual thread stacks are not GC roots. Thus the references they contain are not traversed in a stop-the-world pause by garbage collectors, such as G1, that perform concurrent heap scanning."

Ну так в жабе VT — это костыль из говна и палок поверх ForkJoinPool, рутам там и взяться неоткуда, хотя в VT до сих пор проблему с пиннигом потоков не решили (и они еще и не preemptive).
Отредактировано 06.01.2026 13:17 НепредставимыйПхы . Предыдущая версия .
Re[14]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 06.01.26 13:30
Оценка:
Здравствуйте, НепредставимыйПхы, Вы писали:

N>>>Другое дело что "тем больше рутов, от которых пляшет GC" совершенно не расскрыто. Может и не больше. А может и больше, но это не значит, что оно медленней.

НП>·>Ну нету рутов в виртуальных потоках. Из jep 444: "Unlike platform thread stacks, virtual thread stacks are not GC roots. Thus the references they contain are not traversed in a stop-the-world pause by garbage collectors, such as G1, that perform concurrent heap scanning."
НП>Ну так в жабе VT — это костыль из говна и палок поверх ForkJoinPool
Что в этом плохого? Чем это отличается от async|await?

НП>рутам там и взяться неоткуда, хотя в VT до сих пор проблему с пиннигом потоков не решили.

Какую именно проблему? И где эту же проблему решили?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[15]: Можно ли избавиться от async|await?
От: НепредставимыйПхы КНДР  
Дата: 06.01.26 14:05
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, НепредставимыйПхы, Вы писали:


N>>>>Другое дело что "тем больше рутов, от которых пляшет GC" совершенно не расскрыто. Может и не больше. А может и больше, но это не значит, что оно медленней.

НП>>·>Ну нету рутов в виртуальных потоках. Из jep 444: "Unlike platform thread stacks, virtual thread stacks are not GC roots. Thus the references they contain are not traversed in a stop-the-world pause by garbage collectors, such as G1, that perform concurrent heap scanning."
НП>>Ну так в жабе VT — это костыль из говна и палок поверх ForkJoinPool
·>Что в этом плохого? Чем это отличается от async|await?

Упоротого жавабоя вижу я в тебе, не тебя ли уже гоняли тряпкой по disruptor в треде го?

НП>>рутам там и взяться неоткуда, хотя в VT до сих пор проблему с пиннигом потоков не решили.

·>Какую именно проблему? И где эту же проблему решили?

https://openjdk.org/jeps/491
Re[16]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 06.01.26 14:17
Оценка:
Здравствуйте, НепредставимыйПхы, Вы писали:

НП>>>Ну так в жабе VT — это костыль из говна и палок поверх ForkJoinPool

НП>·>Что в этом плохого? Чем это отличается от async|await?
НП>Упоротого жавабоя вижу я в тебе, не тебя ли уже гоняли тряпкой по disruptor в треде го?
Перешел на личности. А по делу сказать нечего.

НП>>>рутам там и взяться неоткуда, хотя в VT до сих пор проблему с пиннигом потоков не решили.

НП>·>Какую именно проблему? И где эту же проблему решили?
НП>https://openjdk.org/jeps/491
Цитирую: "Status Closed / Delivered". Что сказать-то хотел?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[17]: Можно ли избавиться от async|await?
От: НепредставимыйПхы КНДР  
Дата: 07.01.26 09:15
Оценка:
Здравствуйте, ·, Вы писали:

НП>>·>Какую именно проблему? И где эту же проблему решили?

НП>>https://openjdk.org/jeps/491
·>Цитирую: "Status Closed / Delivered". Что сказать-то хотел?

Да тащемта сказал уже, что хотел: месяц назад закрыли проблему о который ты даже не знал до вчерашнего дня, воистину тяжела жизнь упоротого жавабоя.
Re[18]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 07.01.26 10:27
Оценка: +1
Здравствуйте, НепредставимыйПхы, Вы писали:

НП>>>https://openjdk.org/jeps/491

НП>·>Цитирую: "Status Closed / Delivered". Что сказать-то хотел?
НП>Да тащемта сказал уже, что хотел: месяц назад закрыли проблему о который ты даже не знал до вчерашнего дня, воистину
Вообще-то почти четыре месяца назад. Об этом я уже писал чуть выше
Автор: ·
Дата: 18.12 18:33
, три недели назад. Но ты же не читатель...

НП>тяжела жизнь упоротого жавабоя.

Тебя так интересует моя жизнь! Ох, я так рад, что это взаимно, сладенький.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Можно ли избавиться от async|await?
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.01.26 22:03
Оценка: +1 -1
Здравствуйте, Shmj, Вы писали:

S>Допустим, по умолчанию все функции сделать async, а компилятор уже сам оптимизирует.


В своё время много было разговоров про автоматический параллелизм. Тут и WLIV (привет Эльбрусу), и автоматическая векторизация, и много чего еще.

Но толком не смогли. Трудно компилятору угодать, когда выгоднее параллелить, а когда — последовательно исполнять. Параллелизм дорог и имеет смысл, когда операции достаточно долгие и при этом независимые.

В результате победил ручной параллелизм при наличии поддержки в среде исполнения/языке. Ну, чтобы не писать pthread_create() и т.п., а go func() или тот же async/await.
Re[43]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 12.01.26 08:52
Оценка:
Здравствуйте, ·, Вы писали:

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


S>>Вот смотрю я на асинхронное программирование в Яве

·>Похвально. Ещё посмотри на Structured Concurrency

·>
S>> // передаем в thenAccept обратный вызов
·>

·>Непонятно какое это отношение имеет к virtual threads и к сабжу.

S>> В JavaScript, под влиянием TypeScript пришли к тому, что await значительно лучше чем создание цепочек обратных вызовов

·>Лучше, конечно. Но речь идёт про virtual threads. С ними не нужен ни await, ни цепочки обратных вызовов. Можно писать тупой синхронный код и выполнять на миллионах тредов.

Речь вообще то идет про асинхронный код в общем. virtual threads не покрывает все возможные варианты. Я специально тебе вопросы задавал.

virtual threads хороши для переноса синхронного кода. Но когда мне нужно параллельно запустить несколько задач , скачать с нескольких ресурсов и продолжить после завершения всех скачанных или первого скачанного, то как мне помогут virtual threads?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 12.01.2026 9:02 Serginio1 . Предыдущая версия .
Re[44]: Можно ли избавиться от async|await?
От: Gt_  
Дата: 12.01.26 09:20
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>virtual threads хороши для переноса синхронного кода. Но когда мне нужно параллельно запустить несколько задач , скачать с нескольких ресурсов и продолжить после завершения всех скачанных или первого скачанного, то как мне помогут virtual threads?


тебе же вежливо разжували, зачем дурачком прикидываться ? virtual threads помогут написать сам метод, не задумываясь о параллельности. большая разница на фоне .net, где нужно четко понимать что метод будет частью асинхронного кода и нужно очень внимательно следить, что бы не застопорить всю параллельность на какой-нить и/о ожидании.
Re[45]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 12.01.26 09:50
Оценка:
Здравствуйте, Gt_, Вы писали:


S>>virtual threads хороши для переноса синхронного кода. Но когда мне нужно параллельно запустить несколько задач , скачать с нескольких ресурсов и продолжить после завершения всех скачанных или первого скачанного, то как мне помогут virtual threads?


Gt_>тебе же вежливо разжували, зачем дурачком прикидываться ? virtual threads помогут написать сам метод, не задумываясь о параллельности. большая разница на фоне .net, где нужно четко понимать что метод будет частью асинхронного кода и нужно очень внимательно следить, что бы не застопорить всю параллельность на какой-нить и/о ожидании.


Gt_ не читатель. Еще раз. virtual threads хороши для переноса синхронного кода. Всё!
А вот когда нам нужна параллельность они ну никак в Красную Гвардию не годятся.

Что касается .Net то помню в Windows Mobile были только асинхронные методы. Большинство используют асинхронные методы. Проблем с async/await ни у кого нет.
Что касается неправильного вызова, то есть варнинги и ошибки при компиляции.

Кстати а как virtual threads существуют с FutureTask?
и солнце б утром не вставало, когда бы не было меня
Re[44]: Можно ли избавиться от async|await?
От: · Великобритания  
Дата: 12.01.26 09:59
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> В JavaScript, под влиянием TypeScript пришли к тому, что await значительно лучше чем создание цепочек обратных вызовов

S>·>Лучше, конечно. Но речь идёт про virtual threads. С ними не нужен ни await, ни цепочки обратных вызовов. Можно писать тупой синхронный код и выполнять на миллионах тредов.
S> Речь вообще то идет про асинхронный код в общем. virtual threads не покрывает все возможные варианты. Я специально тебе вопросы задавал.
А ответы-то прочитал?

S>virtual threads хороши для переноса синхронного кода. Но когда мне нужно параллельно запустить несколько задач , скачать с нескольких ресурсов и продолжить после завершения всех скачанных или первого скачанного, то как мне помогут virtual threads?

Ты, похоже, не понимаешь разницу между асинхронным и параллельным исполнением. Это ортогональные понятия.
Ты напишешь обычный синхронный код, который это всё сделает. В этом топике уже несколько раз пережевывалось, перечитай.
Например, для первого скачанного будет как-то так:
Data downloadSomeData(List<URL> urls)
{
  try (var scope = StructuredTaskScope.open(Joiner.<Data>anySuccessfulOrThrow()))
  {
    for(var url : urls)
    {
      scope.fork(() -> service.download(..., url, ...));
    }

    return scope.join();
  }
}

В случае шарпа тебе придётся завести пары методов downloadSomeData/downloadSomeDataAsync, download/downloadAsync и кучу копипасты.

Давай ещё с другой стороны попробую зайти. Вот тут ты написал:
S>var res = await task; // или в синхронном варианте int res = task.Result;
Вот зачем этот выбор? Более того, если ты воткнёшь тут "await", это значит сам метод придётся объявить async. И, возможно, это будет интерфейсный метод, тогда все его имплементации тоже придётся переделывать в async (даже если они простые и без всякой многопоточки/io). И все места вызовов этого метода. И где-то выше по стеку придётся ещё воткнуть await.
Зачем это всё?! Почему нельзя просто всегда писать "int res = task.Result"?
Сабж?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.