【问题标题】:Asynchronous HttpWebRequest Issue with Timer定时器的异步 HttpWebRequest 问题
【发布时间】:2009-08-19 21:29:48
【问题描述】:

情况:我使用的是 msdn 中记录的 HttpWebRequest.BeginGetResponse。我有一个计时器每十秒发送一次请求。我在测试时收到了 xml 结构的信息。

结果:在客户处并运行该工具时,我收到了不完整(因此无法解析)的 xml(每个大约 4KB)。我可以签入浏览器并完整查看(显然是通过浏览器的同步请求?!)。我使用有关内容长度的标头信息来调整接收缓冲区的大小。

是什么原因造成的?我不知道。数据相当小。我仍然使用developer fusion 中描述的ThreadPool.RegisterWaitForSingleObject 方法来定义超时,我也选择了十秒作为超时。也许这不是一个明智的决定,它可能应该比计时器间隔更小。问题是,我无法在这些条件下再次测试它。它在一个生产站点,我对网络设置一无所知。来自家里的请求同时运行得很好。

我在该领域不是很有经验,但是当计时器在完全接收到响应流之前触发新请求时会发生什么,例如超时时间等于定时器间隔?任何其他提示可能是这里的瓶颈?

【问题讨论】:

    标签: c# .net timer


    【解决方案1】:

    您如何接收数据?您是否正在通过流读取数据?您是否使用作为 Stream.Read 的输入参数返回的 contentsize? Stream.Read 的一个不完全明显的特性是它不能保证返回您请求的数据量。 当你调用以下函数时

    public abstract int Read(byte[] buffer, int offset, int count )
    

    它将返回实际读取了多少数据。所以你可以要求它读取 1000,它返回 400,那么还有 600 字节要读取。 这意味着您必须继续调用 Read 直到它返回 0(这意味着流中没有更多数据)。

    我还要说您不应该使用内容长度标头信息来调整缓冲区大小。相反,您应该创建一个动态大小的缓冲区(例如,通过使用 MemoryStream 对象)并从响应流中读取,直到它返回 0。至少,我会这样做。然后,如果服务器更改实现以不再发送该响应标头,那么您的解决方案将继续工作。 甚至更好,因为您正在加载 XML,所以创建一个 XmlDocument,并要求它直接从 Http 响应流中加载。

    【讨论】:

    • 感谢您的提示,我确实似乎误用了 Stream.Read 方法。
    【解决方案2】:

    解决方案很简单。仅在处理完响应后才启动计时器。

    【讨论】:

    • 我想这就是我所需要的。这回答了我所说的如果我需要照顾它的意思。我简直不敢相信我不能在 10 秒内收到 4KB。
    • 但是我的计时器也无法控制某个时间间隔。也许我不应该强迫我的应用程序进入这些间隔,因为这取决于连接质量..
    【解决方案3】:

    如果您连接的是不同的服务器,那么来自服务器的响应也可能被“分块”。我在某处读到 httpwebrequest 有一个错误,在分块服务器上,它不会返回完整文件

    如果是这种情况,请确保服务器没有为 http 流量启用“分块模式”。

    或者,如果这超出您的能力范围,请使用普通套接字自己执行请求,发送 http 请求,然后返回完整的结果。

    在走这条路线之前,首先要确保这个分块模式是这里的问题

    R

    【讨论】:

    • 分块模式也是一种选择,我会尝试了解更多。尽管它必须以某种方式与该网络上的流量相关联,因为正如我所说,它同时在家里的另一台电脑上工作。一旦我发现了什么,我会提供反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多