TcpClient - ожидание получения данных - PullRequest
2 голосов
/ 26 февраля 2010

В моем приложении C # у меня есть поток, который в основном постоянно читает из TcpClient, пока не получит команду остановить. Я использую WaitHandles для этой цели, например:

private ManualResetEvent stopping;

private void Receive()
{
    while (!this.stopping.WaitOne(10))
    {
        while (this.client.Available > 0)
        {
            // Read and process data
        }
    }
}

Как вы видите, я жду, пока поток сообщений не прекратится. Если это не так, он считывает все данные из TcpClient и зацикливается.

У меня проблема с задержкой в ​​10 мсек, которой я бы не хотел. Я мог бы уменьшить его, но я бы предпочел решение, при котором программа будет приостанавливаться до тех пор, пока НИКАКОЙ поток не скажет остановиться или не станет доступно больше данных.

По сути, я хочу WaitHandle, который сообщает мне, когда данные доступны на TcpClient. Таким образом, я могу использовать WaitHandle.WaitAny. Есть ли способ, которым я могу сделать это, или кто-то может предложить альтернативный подход?

Это не может быть уловкой, поскольку это должен быть довольно производительный и легкий фоновый процесс.

1 Ответ

3 голосов
/ 26 февраля 2010

Вам нужно будет использовать метод BeginRead на базовом NetworkStream. Это вернет IAsyncResult, который имеет свойство AsyncWaitHandle. Теперь вы создаете массив из WaitHandle, вставляете AsyncWaitHandle в [0], ManualResetEvent в [1] и затем вызываете WaitHandle.WaitAny() с массивом, и он либо возвращает индекс дескриптора установлен или WaitTimeout на тайм-аут.

Как только вы узнаете, что установлен AsyncHandle, вы можете использовать EndRead, чтобы завершить чтение и получить данные в ваш буфер.

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

...