Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / async await что я делаю не так? / 25 сообщений из 67, страница 1 из 3
01.05.2021, 15:44
    #40067771
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
был такой код:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
static void Main(string[] args)
{
    List<Task> tasks = new List<Task>();
    Stopwatch sw = new Stopwatch();
    sw.Start();

    for (int i = 0; i < 100; i++)
    {
        tasks.Add(Task.Factory.StartNew(() =>
        {
        .........

            bytes = stream.Read(data, 0, data.Length);

        .........
        }));
    }
    Task.WaitAll(tasks.ToArray());

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    Console.ReadLine();
}



Мне нужно было сделать чтение асинхронным, и я переписал так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
static void Main(string[] args)
{
    List<Task> tasks = new List<Task>();
    Stopwatch sw = new Stopwatch();
    sw.Start();

    for (int i = 0; i < 100; i++)
    {
        tasks.Add(Task.Factory.StartNew(async () =>
        {
            .........

            Task<int> readtask = stream.ReadAsync(data, 0, data.Length);
            await readtask;
            bytes = readtask.Result;

            .........
        }));
    }
    Task.WaitAll(tasks.ToArray());

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    Console.ReadLine();
}



Задачи работают как нужно, с этим все ок. Hо вот теперь на Task.WaitAll(tasks.ToArray()); программе стало наплевать, сразу переходит к записи времени в консоль. Как это поправить?
...
Рейтинг: 0 / 0
01.05.2021, 15:48
    #40067773
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Ты все делаешь не так.
...
Рейтинг: 0 / 0
01.05.2021, 16:20
    #40067776
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
...
Рейтинг: 0 / 0
01.05.2021, 17:25
    #40067781
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Сон Веры Павловны,

Честно говоря я не понял что из того, что по ссылке, может помочь.
...
Рейтинг: 0 / 0
01.05.2021, 17:27
    #40067782
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
static async Task Main()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();

    await Task.WhenAll(
        Enumerable.Repeat(0, 100)
             .Select(_ => stream.ReadAsync(data, 0, data.Length)));

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    Console.ReadKey(true);
}
...
Рейтинг: 0 / 0
01.05.2021, 17:57
    #40067787
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
fkthat,

До меня не доходит как можно реализовать это в цикле без использования отдельных задач, ведь переменные будут принадлежать основному потоку и на второй итерации потеряется все от первой...

Мне нужно опросить 100 устройств, и секунд через 5 они вернут результаты измерений в том же соединении. Но запрос нужно подать одновременно на все, чтоб привязаться ко времени для статистики, графиков и т.п.

Для тестов утащил с метанита клиент - сервер. Сервер (многопоточный) изменил так, чтоб между запросом и ответом была задержка 5 секунд. Клиента сделал создающим собственно 100 задач. (для тестов опрашиваю один сервер 100 раз, а не 100 различных устройств)
Если в клиенте читать синхронно, то на эти пять секунд поток блочится, и пул неспешно обрабатывает все по очереди. Если чтение переделать на асинхронное - то все получается как нужно - уходят сразу 100 запросов, через 5 секунд приходят 100 ответов.

Вот полный код
клиент:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {

        const int port = 8888;
        const string address = "127.0.0.1";
        static void Main(string[] args)
        {

            List<Task> tasks = new List<Task>();

            Stopwatch sw = new Stopwatch();
            sw.Start();


            for (int i = 0; i < 100; i++)
            {
                int tmp = i;

                tasks.Add(Task.Factory.StartNew(async () =>
               {
                   TcpClient client = null;
                   try
                   {
                       client = new TcpClient(address, port);
                       NetworkStream stream = client.GetStream();

                       string message = $"qwertyuiop {tmp}";
                       // преобразуем сообщение в массив байтов
                       byte[] data = Encoding.Unicode.GetBytes(message);
                       // отправка сообщения
                       stream.Write(data, 0, data.Length);

                       // получаем ответ
                       data = new byte[64]; // буфер для получаемых данных
                       StringBuilder builder = new StringBuilder();
                       int bytes = 0;
                       do
                       {
                           Task<int> readtask = stream.ReadAsync(data, 0, data.Length);
                           await readtask;
                           //bytes = stream.Read(data, 0, data.Length);
                           bytes = readtask.Result;
                           builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                       }
                       while (stream.DataAvailable);

                       message = builder.ToString();
                       Console.WriteLine("Сервер: {0}", message);

                   }
                   catch (Exception ex)
                   {
                       Console.WriteLine(ex.Message);
                   }
                   finally
                   {
                       client.Close();
                   }



               }));
            }
            Task.WaitAll(tasks.ToArray());

            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }
    }

}



сервер:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ConsoleServer
{
    public class ClientObject
    {
        public TcpClient client;
        public ClientObject(TcpClient tcpClient)
        {
            client = tcpClient;
        }

        public void Process()
        {
            NetworkStream stream = null;
            try
            {
                stream = client.GetStream();
                byte[] data = new byte[64]; // буфер для получаемых данных

                // получаем сообщение
                StringBuilder builder = new StringBuilder();
                int bytes = 0;
                do
                {
                    bytes = stream.Read(data, 0, data.Length);
                    builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                }
                while (stream.DataAvailable);

                string message = builder.ToString();

                Console.WriteLine(message);
                // отправляем обратно сообщение в верхнем регистре

                Thread.Sleep(5000);

                message = message.Substring(message.IndexOf(':') + 1).Trim().ToUpper();
                data = Encoding.Unicode.GetBytes(message);
                stream.Write(data, 0, data.Length);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (stream != null)
                    stream.Close();
                if (client != null)
                    client.Close();
            }
        }
    }

    class Program
    {
        const int port = 8888;
        static TcpListener listener;
        static void Main(string[] args)
        {
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
                listener.Start();
                Console.WriteLine("Ожидание подключений...");

                while (true)
                {
                    TcpClient client = listener.AcceptTcpClient();
                    ClientObject clientObject = new ClientObject(client);

                    // создаем новый поток для обслуживания нового клиента
                    Thread clientThread = new Thread(new ThreadStart(clientObject.Process));
                    clientThread.Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (listener != null)
                    listener.Stop();
            }
        }
    }



}

...
Рейтинг: 0 / 0
01.05.2021, 19:19
    #40067790
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Переделал вот так. Не знаю правильней так или нет... Кстати заметил что в обоих вариантах что-то не то с циклом приема, если буфер меньше сообщения ерунда получается :(

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        const int port = 8888;
        const string address = "127.0.0.1";
        const int num = 100;
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            TcpClient[] clients = new TcpClient[num];
            Task[] tsk_write = new Task[num];
            Task<int>[] tsk_read = new Task<int>[num];

            for (int i = 0; i < num; i++)
            {
                int tmp = i;
                try
                {
                    clients[i] = new TcpClient(address, port);
                    NetworkStream stream = clients[i].GetStream();

                    string message = $"qwertyuiop {tmp}";

                    byte[] data = Encoding.Unicode.GetBytes(message);

                    tsk_write[i] = stream.WriteAsync(data, 0, data.Length);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            Task.WhenAll(tsk_write).Wait();

            for (int i = 0; i < num; i++)
            {
                try
                {

                    byte[] data = new byte[64];
                    StringBuilder builder = new StringBuilder();
                    int bytes = 0;
                    do
                    {
                        tsk_read[i] = clients[i].GetStream().ReadAsync(data, 0, data.Length);
                        bytes = tsk_read[i].Result;
                        builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                    }
                    while (clients[i].GetStream().DataAvailable);

                    string message = builder.ToString();
                    Console.WriteLine("Сервер: {0}", message);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    clients[i].Close();
                }
            }
            Task.WhenAll(tsk_read).Wait();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }
    }
}
...
Рейтинг: 0 / 0
01.05.2021, 19:31
    #40067792
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Хотя в таком виде оно и в синхронном варианте нормально работает. Но это не совсем то, что я хотел - в таком виде придется дожидаться максимального по задержке запроса чтобы продолжить дальше. А в тасках можно было бы обрабатывать по приходу ответа.
...
Рейтинг: 0 / 0
01.05.2021, 19:56
    #40067798
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Если попытаться сформулировать... Мне нужно чтоб не блочился поток в пуле на время ожидания, но при этом чтоб прием данных происходил не в одном потоке, а в нескольких, в пуле. Ну то-есть разослали хоть тысячу запросов и ждем хоть год. А как пришел ответ (скажем пришли ответы от 10 одновременно) - получаем и обрабатываем его в несколько потоков (ну сколько там пул решит оптимальным)
...
Рейтинг: 0 / 0
01.05.2021, 23:01
    #40067822
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql,
как бы немножко обескуражен, от вашего кода. Имхо возникает масса вопросов про таски, абстракция для работы с потоками,
вот такая вот обструкция, что у многих сностит голову. А сносит, имхо из-за того, что отстутствуют так назывые понятия thread
и как устроены пулы.
что любят потоки, - самодостаточность, все что нужно, лежит внутри, никакого общения с наружностью, никаких общих
переменных, только в крайнем случае, как пример отдать результат., все что нужно, он получает при создании..
вы пошли в поход, все что нужно взяли с собой, ну и спутник,( позвонить маме что вы на вершине), никаких петь ( взять веревку когда полезем в гору)
что делает поток - поток выпоняет осмысленный кусок кода ( есть начало и есть конец) ба да... да это фукция.
получается, что бы поток запустился, в него нужно передать указатель на этот кусок ( или название функции, или написать ее
в виде лямбды по месту обьявления ( я опуская слово делегат что бы не морочить вам голову))
у потока есть интересная особенность, когда он исполнит код, он умирает ( про поход пример неудачный), как правило, за редким исключением.
если создать массу потоков, ими можно упралять как стадом баранов (синхронизация потоков).
в контексте вышесказанного.
вы должны стереть все нах.
1 содать статическую функцию закачки данных. оттестировать ее, то есть,
в главном методе( точке входа) только вызов этой функции, никаких бл. бенчмаркеров, ничего статического, кроме этой функции.
можете передать в параметрах - куда лезем.
почему статик ( для верочки, что шалавливые ручки не сделали замыкание)
2 проверить.
если все нормально - вы доросли до потока.
потом проще
создаемем список, ( желательно реентерабельный) и только чтение ( защитимся комилятором от шаловливых рук), куда будем выводить результат, если хочешь его обрабатывать
делай очередь, с одного конца закидывай результат, с другого выгребай на обработку (если не пустая)
Одни поток - запускаем
внизу ставим цикл прослушки списка, если в списке нуль - крутимся если 1 - поток отработал.
если все ок, делаем 100 потоков, в прослушке уже ловим 100.
и не забывать, что ексепешн - тоже результат ( а то замерзнешь до второго пришествия)
хочешь запустить их по зеленому сигналу светофора - кури синхронизацию потоков.
бенчмарки свои - можно спрятать в поток и отдать с результатом ( имхо более приближенно)
забудь про таски, таски потом...
жаль студия на работе - показал бы механизм создания свой пула потоков (10 - 20 строк кода) и забыть про таски..
имхо может завтра..
...
Рейтинг: 0 / 0
02.05.2021, 02:17
    #40067838
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql
Код: c#
1.
Task.WhenAll(tsk_write).Wait();


В печь.

iskatelsql
Код: c#
1.
Task.WhenAll(tsk_read).Wait();


В печь.
...
Рейтинг: 0 / 0
02.05.2021, 02:20
    #40067839
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Где-то в степи
А сносит, имхо из-за того, что отстутствуют так назывые понятия thread
и как устроены пулы.

Сносит, имхо, из-за того, что отсутствуют так называемые понятия асинхронности.

Тут сплошной i/o - все вообще можно в одном потоке сделать с той же эффективностью.
...
Рейтинг: 0 / 0
02.05.2021, 02:51
    #40067840
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Ну давайте, наседайте... Ваше право. Я вообще в первый раз с этой асинхронностью.
Сказал уже что нужно - обрабатывать результат во множестве потоков, но так чтоб пул не блокировался, и ожидающие шли ждать.
...
Рейтинг: 0 / 0
02.05.2021, 03:00
    #40067842
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
Где-то в степи,

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

ЗЫ. воспользоваться тем механизмом, не переписывать его.
...
Рейтинг: 0 / 0
02.05.2021, 03:06
    #40067843
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
как бы немножко обескуражен, от вашего кода.
я как- бы зашел спросить, то чего не знаю. По правилам нужно предоставить то, что сделал, что пытался сделать - я предоставил, оно работает даже. Что еще нужно?
...
Рейтинг: 0 / 0
02.05.2021, 03:12
    #40067844
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
как бы немножко обескуражен, от вашего кода.

я как- бы зашел спросить, то чего не знаю. По правилам нужно предоставить то, что сделал, что пытался сделать - я предоставил, оно работает даже, ну почти...

А даже не почти, а работает - конкретный вопрос был: от чего не ждет на Task.WaitAll(tasks.ToArray());

Так сложно именно на этот вопрос ответить?

Вы наверное забываете что разговариваете с самоучкой, а не с, как это называется, "сеньор разработчик" что-ли.
...
Рейтинг: 0 / 0
02.05.2021, 04:00
    #40067846
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql
А даже не почти, а работает - конкретный вопрос был: от чего не ждет на Task.WaitAll(tasks.ToArray());


Если в лоб.
Метод же возвращает Task.
Т.е. вернул запущенную асинхронно задачу.
А не результат выполнения.

Обращайте внимание не только на название метода, но и на то, что он возвращает.
По идее, асинхронные методы в названии должны иметь суффикс -Async, но не все и не всегда этому следуют.
...
Рейтинг: 0 / 0
02.05.2021, 04:04
    #40067847
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql,

Я минимально поправил код, приведённый в начале топика, добавленное выделено цветом.
Понятно, что выше приводили разные вариации, это именно минимальное исправленеи вашего кода, чтобы заработало. Но конечно есть к чему ещё придраться.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
static async Task Main(string[] args)
{
    List<Task> tasks = new List<Task>();
    Stopwatch sw = new Stopwatch();
    sw.Start();

    for (int i = 0; i < 100; i++)
    {
        tasks.Add(Task.Run(async() =>  // убрал вот этоTask.Factory.StartNew(async () =>
        {
            .........

            Task<int> readtask = stream.ReadAsync(data, 0, data.Length);
            await readtask;
            bytes = readtask.Result;

            .........
        }));
    }
    await Task.WaitAll(tasks.ToArray());

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    Console.ReadLine();
}
...
Рейтинг: 0 / 0
02.05.2021, 04:12
    #40067848
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
hVostt,

static async Task Main
Вот это обескураживающая меня конструкция, на которую компилятор ругается что нечего компилировать нет точки входа (vs 2019).
...
Рейтинг: 0 / 0
02.05.2021, 04:17
    #40067849
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql,

посмотрите здесь

https://docs.microsoft.com/ru-ru/dotnet/csharp/misc/cs4009

вам нужно настроить, что используется последняя версия языка C#



...
Рейтинг: 0 / 0
02.05.2021, 04:20
    #40067850
iskatelsql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql
hVostt,

static async Task Main
Вот это обескураживающая меня конструкция, на которую компилятор ругается что нечего компилировать нет точки входа (vs 2019).


Хотя на пустом проекте сейчас это сработало. (раньше пытался изменить существующий)

Беру паузу, буду думать.
Спасибо Вам.
...
Рейтинг: 0 / 0
02.05.2021, 10:29
    #40067857
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
hVostt
Код: c#
1.
await Task.WaitAll(tasks.ToArray());

fkthat
В печь.
...
Рейтинг: 0 / 0
02.05.2021, 10:31
    #40067858
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
fkthat
hVostt
Код: c#
1.
await Task.WaitAll(tasks.ToArray());


fkthat
В печь.

А, все, понял. Ты просто перепутал WaitAll и WhenAll. У меня на Wait или Result уже просто рефлекторная реакция.
...
Рейтинг: 0 / 0
02.05.2021, 10:37
    #40067859
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
hVostt
но не все и не всегда этому следуют.

Знал одних уродов, которые принципиально -Async не дописывали. И я с их кодом провозился полчаса на вызове как-то так:
Код: c#
1.
var userId = _userService.GetUser(...).Id;


Потому что GetUser возвращал Task. Сказано в букваре - дописывать -Async и ConfigureAwait, значит нехер какие-то свои половые фантазии выдумывать.
...
Рейтинг: 0 / 0
02.05.2021, 11:19
    #40067863
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async await что я делаю не так?
iskatelsql,
да ничего вы не знаете, по этому разговариваю с вами как с ребенком,
гыгы знаю потоки но не могу писать асинхронный код.
ну да ладно, самое прикольное, когда вы пинками все исправите, и все будет партикулярно.
цена вашего кода будет меньше цены бумаги на которой он написан.
потому что: на простом декстопе на стандартным core5, нативные потоки будут исполняться быстрее примерно в 5 раз
чем пуловые, и вы виртуалного работатдателя введете в заблуждение. ( я кончно исключаю что это пром. решение)
зы гы
а еще, с вашими хотелками, (работать по свистку) тут ИМХО не совсем получится, и можно попасть в замок.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / async await что я делаю не так? / 25 сообщений из 67, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]