Intereting Posts
Что означает компилятор C #, когда он печатает «явное преобразование существует»? Неправильно созданные выходные папки с Visual Studio 2008 Как получить значения словаря в качестве общего списка Указанный приказ недействителен. Как решить эту проблему Метод ReceiveAsync для websocket не ожидает полного сообщения ASP.Net: Пользовательский контроль с областью содержимого, это очевидно, но мне нужны детали c # winform background worker и индикатор выполнения Получить последний не пустой столбец и индекс строки из excel с помощью Interop Инструмент для обратной совместимости для API C # /. NET? Поиск REST с клиентской библиотекой JSON использование и объяснение синтаксиса => C # – Получить тип элемента для общего списка Как изменить регистрацию зависимостей во время выполнения с использованием простого инжектора? Создание JSON Webservice с использованием C # .NET Должны ли вы повторно использовать объекты SqlConnection, SqlDataAdapter и SqlCommand?

Внедрение тайм-аута с помощью NetworkStream.BeginRead и NetworkStream.EndRead

Я написал следующую функцию для реализации функции тайм-аута, используя функции асинхронного чтения NetworkStream ( BeginRead и EndRead ). Он отлично работает, пока я не прокомментирую строку Trace.WriteLine("bytesRead: " + bytesRead); , Зачем?

 private int SynchronousRead(byte[] buffer, int count) { int bytesRead = 0; bool success = false; IAsyncResult result = null; result = _stream.BeginRead( buffer, 0, count, delegate(IAsyncResult r) { bytesRead = _stream.EndRead(r); }, null); success = result.AsyncWaitHandle.WaitOne(_ioTmeoutInMilliseconds, false); if (!success) { throw new TimeoutException("Could not read in the specfied timeout."); } //If I remove this line, bytesRead is always 0 Trace.WriteLine("bytesRead: " + bytesRead); return bytesRead; } 

На всякий случай, когда вам интересно, я должен это сделать, потому что мне в конечном итоге нужно настроить таргетинг на .Net Compact Framework 3.5 и не поддерживает свойства NetworkStream.ReadTimeout и NetworkStream.WriteTimeout .

Интересная ошибка в streamе. Переменная bytesRead назначается после того, как сигнализируется команда wait. Две вещи могут пойти не так: метод возвращается до выполнения задания. Или stream читает устаревшее значение, так как они не являются защитой памяти от вызова WaitOne (). Оператор Trace исправляет проблему, потому что он задерживает основной stream достаточно долго, чтобы разрешить запись переменной. И он имеет внутреннюю блокировку, обеспечивающую целостность кеша.

Вам понадобится дополнительный AutoResetEvent, который сигнализирует, что была записана переменная bytesRead.

Помимо проблемы с барьером памяти в вашем коде (как указал Ханс), если бы я был вами, я бы использовал Reactive Extension вместо этого, чтобы этот сегмент кода состоял всего из трех строк кода. Если у вас есть время, я настоятельно рекомендую вам использовать Rx вместо этого.

ура