Проблема блокировки Networkstream.Write ()

В настоящее время я тестирую управляемую сетевую библиотеку C #, написанную мной, и время от времени сталкивался с проблемой. Эта проблема проявляется в виде очень последовательного (всегда в пределах 30 мс) блока 5000 мс в networkstream.write (), возможно, для 1% всех операций отправки. Это тестовая среда, все выполняются локально, каждый раз используя один и тот же размер пакета (2 МБ). На стороне клиента я постоянно записываю в подключенный сетевой поток следующее:

tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length);
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length);

, а на стороне сервера я использую асинхронное чтение, ожидающее данных. Как только данные появятся, я использую цикл while с tcpClientNetworkStream.DataAvailable, пока все данные не будут получены.

Мне известно, что networkstream.write () может блокироваться, если буферы заполнены, но если это проблема, я не могу придумать более быстрого способа их очистки на стороне сервера (размеры буфера отправки и получения по умолчанию равны 8192 байта). Тот факт, что блок такой последовательный, кажется очень странным. Моя первая мысль была, возможно, какой-то формой Thread.Sleep, но полный поиск по проекту ничего не показал. Если бы кто-нибудь мог помочь пролить свет на эту проблему, он был бы очень признателен.

Марк

отредактируйте, чтобы добавить: Взлом, который, кажется, решает проблему, заключается в следующем (хотя есть связанное с этим снижение производительности из-за BlockCopy):

byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length];
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length);
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length);
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length);

отредактируйте в add2: Я также воспроизвел проблему, используя две асинхронные записи с сигналом потока между ними. На данный момент единственное решение, которое у меня есть, - это одна операция записи, как в приведенном выше редактировании.

редактировать в add3: Хорошо, следует другое возможное исправление. Мне все еще интересно узнать, почему последовательная запись иногда «блокируется» таким образом.

BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream);
sendStream.Write(bytesToSend, 0, bytesToSend.Length);
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length);
sendStream.Flush();

edit to add4: После дальнейшего обширного тестирования решение в «edit to add3» не устраняет проблему, а просто снижает частоту отправки примерно до 0,1%. Намного лучше, но это далеко не решено. Я заменю асинхронное чтение блокирующим чтением рядом, чтобы посмотреть, сортирует ли это его, как предлагает PaulF.

6
задан MarcF 26 August 2011 в 11:06
поделиться