【问题标题】:C# StreamReader causing +200ms overhead to read data from sourceC# StreamReader 导致 +200ms 开销从源读取数据
【发布时间】:2017-02-28 00:13:04
【问题描述】:

当系统有负载时,我们看到从流读取器读取输入流时会出现周期性的 +200 毫秒开销。我想知道有没有其他人看到这个,如果他们做了什么来解决它?

以下是代码:

string requestBody;
var streamReaderTime = Stopwatch.StartNew();
using (var streamReader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
{
    var allLines = streamReader.ReadLines();
    var request = new StringBuilder();
    allLines.ForEach(line => request.Append(line));
    requestBody = request.ToString();
}
streamReaderTime.Stop();

ReadLine 如下:

public static IEnumerable<string> ReadLines(this StreamReader reader)
{
   while (!reader.EndOfStream)
   { 
     yield return reader.ReadLine();
   }
}

注意:如果有的话,使用 ReadLines() 或 ReadToEnd() 几乎没有区别。

我们在一夜之间运行性能测试,仅通过绘制 streamReaderTime 图形我们就看到了以下行为。

单个请求的执行时间在 45 毫秒到 70 毫秒之间,但从屏幕截图中可以看出,它正在增加一个固定值,有时甚至会出现更大的峰值。我在大约 1.5 秒之前看到了它。

如果有人有任何解决方案/建议,将不胜感激。

编辑:我确实有 ReadToEnd() 而不是 ReadLines() 并且摆脱了 StringBuilder 但它仍然是相同的开销。有没有 StreamReader 的替代品,只是为了测试一下?看起来确实像 GC 成本,因为每十秒发出一次请求不会影响它,但是每秒完全相同的请求会导致这种开销发生。此外,我也无法在本地重现它,只有在虚拟环境中才会发生这种情况。

【问题讨论】:

  • 忘记添加了,平均有效载荷大小约为 62.6 KiB。有效负载大小似乎没有任何影响。
  • 您的代码会产生大量垃圾,很有可能您的 Stopwatch 正在测量垃圾收集开销。
  • 我确实有 ReadToEnd() 而不是 ReadLines() 并且摆脱了 StringBuilder 但它仍然是相同的开销。 StreamReader 有替代品吗?看起来确实像 GC 成本,因为每十秒有一个请求不会影响它,但是每秒一个请求会导致这种开销发生。我也无法在本地复制它。我将使用这些详细信息更新我的问题。

标签: c# .net service streamreader


【解决方案1】:

上面的代码根本没有这个问题。问题来自调用者。服务调用正在使用一个库,该库将连接提前切断,并且开销是重新建立连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2018-09-27
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多