【问题标题】:HttpWebRequest and HttpWebResponse ideal async buffer sizesHttpWebRequest 和 HttpWebResponse 理想的异步缓冲区大小
【发布时间】:2011-12-01 17:59:35
【问题描述】:

我正在尝试在 .NET 3.5 中使用 HttpWebRequest 和 HttpWebResponse,以异步方式运行它们:BeginGetRequestStream、EndGetRequestStream、BeginWrite、EndWrite、BeginGetResponse、EndGetResponse、BeginRead、EndRead - 处理请求的所有部分都是异步的。

我有几个线程发送大量并发请求。 EndRead 和 EndWrite 都是阻塞操作——它们阻塞当前线程,同时对流的实际读/写完成,我正在尝试为这些操作提供一个理想的输入/输出缓冲区大小。

我的理由是:由于我有多个请求同时处于活动状态,它们会不断触发回调以让线程知道有一些数据可用或已发送数据。如果我的缓冲区很大,通过线路读取/写入数据将花费更长的时间,因此 EndRead/EndWrite 将阻塞更长的时间。这将迫使同一线程上的其他请求等待更长的时间,因为它们的通知必须等到线程被解除阻塞。

所以,我的问题是,在这种情况下,什么是好的读/写缓冲区大小。我在想每个 2048 字节,但我在各种博客中看到的一些示例代码显示了截然不同的值。

提前感谢您的任何想法。

【问题讨论】:

    标签: c# asynchronous httpwebrequest httpwebresponse


    【解决方案1】:

    我认为更好的解决方案是不要过多担心缓冲区大小,但不要阻塞线程。如果您将委托传递给Begin* 方法的callback 参数,则该回调将在操作完成时执行,您可以从那里调用End*,这将(几乎)立即返回。无需阻塞。

    关于缓冲区大小,如果它们对您真的很重要,您应该分析并找出在您的特定情况下最有效的方法。

    【讨论】:

    • [如果您将委托传递给 Begin* 方法的回调参数,则该回调将在操作完成时执行,您可以从那里调用 End*,它将(几乎)立即返回。无需阻塞]。有趣的是,谁做真正的“开始*”工作。它是 ThreadPool 中的一个线程,它为您执行呼叫+等待。与创建自己的线程做同样的工作有什么不同?
    • 这取决于。但在 IO 操作的情况下,IO completion ports are used。这意味着Begin 方法开始工作并设置端口。工作完成后,端口触发并在线程池线程上执行回调。这与为此创建新线程不同,因为创建新线程总是分配一百万字节。
    • 所以你说,BeginA 在一个委托 fxn 中等待,在那个 fxn 中开始 BeginB 在另一个委托中等待等(而不是在线程中调用 A();B())你真的知道吗?他的代码需要这种复杂性。正如我在回答中所说的“过早的优化是万恶之源”
    • 我没有说任何等待。正如 OP 所说,如果存在“大量并发请求”,这并不是过早的优化。
    • 我知道。等待由使用 BeginA* 函数创建(或已经工作)的线程完成,并且在结果准备好时调用您的委托。这只是为了简化工作流程。我不知道你会发现它与这个问题有多大关系,但是我喜欢这个博客(chaosinmotion.com/blog/?p=622)
    【解决方案2】:

    除了避免明显的极端情况外,您应该设置的实际值没有明确的规则。这实际上取决于您要传输的数据类型以及数据量。您可能希望将写入缓冲区设置得相当高,但将读取缓冲区设置得较低。这是因为在这种情况下,写入(通常)比读取更昂贵。

    在这种情况下,最好的办法是尝试几个值,看看它们的扩展性如何。如有必要,您可以随时更改它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多