Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2018, 00:53   #1
New man
Форумчанин
 
Регистрация: 24.01.2011
Сообщений: 774
По умолчанию Запуск параллельного Task из другого Task.

Собственно, есть у меня приложение, которое выступает в качестве сервера. Есть некоторая куча клиентов, которые подключаются к нему по TCP и отсылают каждый как минимум раз в секунду хертбит (сигнал с некоторой информацией о своём состоянии).

Насколько нормально обработку хертбитов сделать в виде асинхронного таска, который после обработки каждого хертбита запускает самого себя?
Может, есть какие-то грабли?

Собственно, тут отмечено:
Код:
    class Program
    {
        public delegate void MessageReceivedHandler(object sender, EventArgs args);
 
        public event MessageReceivedHandler OnReceived;
        public event MessageReceivedHandler OnLost;
 
        private TcpListener listener;
 
        private void Work()
        {
            listener = TcpListener.Create(9000);
            listener.Start();
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                Task.Run(async () => await HandleClient(client));
            }
        }
 
        private long call_count;
 
        private async Task HandleClient(TcpClient client)
        {
            try
            {
                byte[] buffer = new byte[1024];
                int read = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);
                OnReceived?.Invoke(this, new EventArgs());
                await client.GetStream().WriteAsync(buffer, 0, read);
                Task.Run(async () => await HandleClient(client));   // Насколько вот это хорошо?
            }
            catch
            {
                OnLost?.Invoke(this, null);
                client?.Close();
            }
        }
 
        static void Main(string[] args)
        {
            new Program().Work();
        }
    }
Второе: что поменяется, если я изменю эту строчку вот так?
Код:
await Task.Run(async () => await HandleClient(client));
a.k.a. Angelicos Phosphoros
Мой сайт
New man вне форума Ответить с цитированием
Старый 05.11.2018, 01:51   #2
New man
Форумчанин
 
Регистрация: 24.01.2011
Сообщений: 774
По умолчанию

Я понял, что можно было написать так:

Код:
        private async Task HandleClient(TcpClient client)
        {
            try
            {
                byte[] buffer = new byte[1024];
                while (true)
                {
                    int read = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);
                    OnReceived?.Invoke(this, new EventArgs());
                    await client.GetStream().WriteAsync(buffer, 0, read);
                }
            }
            catch
            {
                OnLost?.Invoke(this, null);
                client?.Close();
            }
        }
Этот вариант потратил в 2 раза меньше Total CPU time, если верить профилировщику.
a.k.a. Angelicos Phosphoros
Мой сайт
New man вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Task manager KaTVisiom Помощь студентам 2 23.04.2018 09:49
Task BlackTerror Паскаль, Turbo Pascal, PascalABC.NET 1 29.10.2017 01:38
Вопрос по Task.Wait(); max_prorok C# (си шарп) 5 09.06.2016 16:43
тестовый вопрос структура Task KVANTA Помощь студентам 4 16.01.2015 19:39
LISP task Arrioh Помощь студентам 0 13.05.2014 14:36