(C#/.NET 8.0) Почему я не могу получать, а затем отправлять данные из UdpClients, созданных и используемых в отдельных потоках?

Я работаю над консольным приложением, которому необходимо получать данные от двух локальных конечных точек и впоследствии отправлять эти данные на две удаленные конечные точки - параллельно. У меня есть код для получения/отправки данных в задаче, который выглядит следующим образом:

public async Task RecvAndSend(DataObj data, bool isRequest)
{
    try
    {
        using var recv = new UdpClient(data.localPort);

        using var send = new UdpClient();

        var remoteEndpoint = new IPEndPoint(data.remoteAddress, data.remotePort);

        while (true)
        {
            try
            {
                byte[] res = (await recv.ReceiveAsync()).Buffer;

                await send.SendAsync(res, res.Length, remoteEndpoint);
                
                Console.Write(isRequest ? "-" : "~");
            }
            catch (Exception ex) {
                Console.WriteLine("Exception thrown in while loop: {0}", ex.Message);
            }
            
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Эта задача принимает 2 параметра. Первыми являются данные, относящиеся к локальному порту, на который эта задача будет получать данные, и удаленному адресу, на который она будет пересылать эти данные.

Как я уже упоминал, два экземпляра этой задачи должны выполняться параллельно. Один экземпляр называется задачей «Запрос», а другой — задачей «Ответ». Я передаю логическое значение (isRequest), которое можно использовать для записи символа в консоль для любой задачи, только что завершившей итерацию цикла while.

Я начинаю эти параллельные задачи следующим образом:

Task t1 = RecvAndSend(requestData, true);
Task t2 = RecvAndSend(responseData, false);

await Task.WhenAll(t1, t2);

Проблема в том, что первая задача начнет получать/отправлять данные, но как только вторая задача начнет получать/отправлять данные, первая задача останавливается. Итак, мой вывод выглядит примерно так:

-------~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Я ожидаю увидеть следующее:

-~-~-~-~-~-~

Возможно, это не так синхронно, но вы поняли.

Я пробовал создавать отдельные UdpClients для отправки и получения внутри каждой задачи, а также пробовал объявлять глобальные клиенты, предназначенные для получения/отправки, и использовать механизм блокировки внутри задачи.

Ничто не сработало так, как ожидалось. На данный момент я не уверен, возможно ли вообще иметь 2 потока с двумя UdpClient, каждый из которых получает и отправляет одновременно.

Они используют одни и те же номера локальных портов?

Charlieface 21.06.2024 01:38

@Charlieface Нет, я выделяю отдельные порты для каждого клиента.

Valente Arellano 21.06.2024 15:22

Для начала — выньте блоки try/catch и посмотрите, какую информацию вам выдает отладчик.

Enigmativity 23.06.2024 06:40

@Enigmativity Удалены блоки try/catch, и от отладчика ничего не получено. Все еще вижу, что моя первая задача приема/отправки останавливается после запуска второй. Я установил точку останова для своей первой задачи и увидел, что свойство UdpClient.Active имеет значение false после запуска второй.

Valente Arellano 24.06.2024 15:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я смог решить эту проблему. Моя проблема оказалась связана с номером порта. Я создавал отдельный клиент для отправки данных, которые были привязаны к случайному доступному порту, выбранному ОС. Получив эти данные, сервер назначения начал отвечать на этот случайный порт, а не на порт, с которого он первоначально начал отправлять данные. По этой причине мой принимающий клиент остановился как вкопанный. Через порт, от которого он ожидал данные, больше не поступали данные.

Другие вопросы по теме

Похожие вопросы

Как я могу получить указатель на управляемую функцию для предоставления неуправляемому коду в качестве обратного вызова?
Выполнение сценария PowerShell с аргументами из кода C#
Получение сообщения с помощью Azure.Messaging.ServiceBus, отправленного с помощью Microsoft.ServiceBus.Messaging (ServiceBus.v1_1)
Передача значений нескольких элементов управления через кнопку в WinUI 3
Функции Azure не принимают значение в кодировке URL-адреса в качестве параметра запроса?
Как выбрать отдельные элементы из таблицы по переменной, а затем присоединиться к другой таблице в LINQ
Установите для свойства высоты стиля кнопки в дизайне материала в XAML значение по умолчанию
Azure SignalR: ни один из транспортных средств, поддерживаемых клиентом, не поддерживается сервером
Angular 17 и dot net Core 8 – добавление Jwt при обновлении в аудиторию
Почему RunContinuationsAsynchronous является недопустимым параметром продолжения для TaskFactory