首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NetworkStream.BeginRead和NetworkStream.EndRead实现超时

使用NetworkStream.BeginRead和NetworkStream.EndRead实现超时
EN

Stack Overflow用户
提问于 2011-10-08 20:39:55
回答 2查看 5.6K关注 0票数 4

我已经使用NetworkStream的异步读取函数(BeginReadEndRead)编写了以下函数来实现超时功能。它工作得很好,直到我注释掉Trace.WriteLine("bytesRead: " + bytesRead);行。为什么?

代码语言:javascript
复制
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 Framework3.5为目标,而它不支持NetworkStream.ReadTimeoutNetworkStream.WriteTimeout属性。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-08 21:06:23

一个有趣的线程bug。bytesRead变量在等待句柄发出信号后赋值。有两件事可能出错:方法在赋值之前返回。或者线程读取一个陈旧的值,因为它们在WaitOne()调用之后没有内存屏障。Trace语句修复了这个问题,因为它会延迟主线程足够长的时间来允许写入变量。而且它有一个内部锁来确保缓存的一致性。

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

票数 5
EN

Stack Overflow用户

发布于 2011-10-08 23:43:35

除了你代码中的内存障碍问题(正如Hans还指出的那样),如果我是你,我会使用反应式扩展,这将使这段代码只有三行代码。如果您有时间,我强烈建议您使用Rx。

干杯

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7696856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档