c# - 使用 NetworkStream.BeginRead 和 NetworkStream.EndRead 实现超时

标签 c# .net asynchronous networkstream

我编写了以下函数来使用 NetworkStream 的异步读取函数(BeginReadEndRead)实现超时功能。它工作正常,直到我注释掉行 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 属性。

最佳答案

一个有趣的线程错误。 bytesRead 变量在等待句柄发出信号后被赋值。有两件事可能会出错:方法在赋值完成之前就返回了。或者线程读取过时值,因为它们在 WaitOne() 调用之后没有内存障碍。 Trace 语句解决了这个问题,因为它延迟了主线程足够长的时间以允许写入变量。它有一个内部锁,确保缓存是一致的。

您将需要一个额外的 AutoResetEvent 来表示已写入 bytesRead 变量。

关于c# - 使用 NetworkStream.BeginRead 和 NetworkStream.EndRead 实现超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7696856/

相关文章:

javascript - 异步 Lambda 函数 : Returning promise or sending responseURL does not terminate CloudFormation custom resource invocation

c# - 以编程方式调用并呈现 Powerpoint 演示文稿

c# - 向现有 XML 文件中的多个节点添加新元素

C# 在下一行之前等待或暂停 X 秒

.net - VS2010+甲骨文驱动: ORA-12154: TSN:could not resolve the connect identifier specified

c# - 在 C# 中查询 netsh

c# - 计算两个数: what's the meaning of optimizations?的算术平均值(average)

asynchronous - flink的sink只支持bio吗?

c++ - boost::asio 接受套接字错误已经打开

c# - 什么是基类构造函数以及为什么要使用它? (附示例)