【问题标题】:Consuming a HTTP stream without reading one byte at a time使用 HTTP 流而不一次读取一个字节
【发布时间】:2012-12-12 00:01:57
【问题描述】:

我一直在尝试使用 C# 从 Twitter 流 API 读取数据,由于有时 API 不会返回任何数据,而我正在寻找接近实时的响应,所以我一直在犹豫是否使用更大的缓冲区长度如果流在接下来的一两天内没有返回任何数据,则读取器上的字节数超过 1 个字节。

我一直在使用以下行:

input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null); 
//buffer = new byte[1]

现在我计划扩大应用程序的规模,我认为大小为 1 会导致大量 CPU 使用率,并希望增加该数量,但我仍然不希望流只是阻塞。如果在接下来的 5 秒内没有读取更多字节或类似情况,是否可以让流返回?

【问题讨论】:

    标签: c# asp.net .net stream


    【解决方案1】:

    异步选项

    如果没有接收到字节,您可以在异步回调方法中使用计时器来完成操作,例如5秒。每次接收到字节时重置定时器。在 BeginRead 之前启动它。

    同步选项

    或者,您可以使用底层套接字的 ReceiveTimeout 属性来确定在完成读取之前等待的最长时间。您可以使用更大的缓冲区并将超时设置为例如5 秒。

    MSDN documentation 来看,该属性仅适用于同步读取。您可以在单独的线程上执行同步读取。

    更新

    这是从类似问题拼凑而成的粗略、未经测试的代码。它可能不会按原样运行(或没有错误),但应该给你这个想法:

    private EventWaitHandle asyncWait = new ManualResetEvent(false);
    private Timer abortTimer = null;
    private bool success = false;
    
    public void ReadFromTwitter()
    {
        abortTimer = new Timer(AbortTwitter, null, 50000, System.Threading.Timeout.Infinite);
    
        asyncWait.Reset();
        input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null);
        asyncWait.WaitOne();            
    }
    
    void AbortTwitter(object state)
    {
        success = false; // Redundant but explicit for clarity
        asyncWait.Set();
    }
    
    void InputReadComplete()
    {
        // Disable the timer:
        abortTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
        success = true;
        asyncWait.Set();
    }
    

    【讨论】:

    • 由于 Twitter 的政策,我不能一直打开和关闭连接。你能举个例子说明我如何使用异步回调计时器提前终止读取吗?
    • @huadianz:添加了一个粗略的例子给你一个起点。
    • 读取是否返回缓冲区中的任何数据,或者该数据是否丢失?
    • @huadianz: 缓冲区应该包含您目前读取的所有数据,即使读取在 5 秒后中止。
    猜你喜欢
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2015-12-11
    • 2023-01-31
    相关资源
    最近更新 更多