【发布时间】:2018-09-03 15:17:21
【问题描述】:
我有以下代码,由于某种原因,ToArray() 方法对单个元素需要 7 毫秒。该应用程序有几个工作线程发生这种情况,我还使用 JetBrains dotTrace 分析了该应用程序,这表明该线程正在等待另一个线程(而不仅仅是等待 CPU),这显然是不可能的,因为List 是一个局部变量,我不使用锁。
List<TransactionType> transactionTypes =
new List<TransactionType>(_TransactionTypes.LengthNull() +
drawingAction._TransactionTypes.LengthNull())
...
Stopwatch sw = Stopwatch.StartNew();
_TransactionTypes = transactionTypes.ToArray();
sw.Stop();
if (sw.ElapsedMilliseconds > 3)
{
int deb = 0;
}
这种现象几乎发生在使用 .Net 框架的方法(例如 String.Format)的每个地方。我有这个问题有一段时间了,由于某种原因,在主线程中使用 SpinWait 会使情况变得更糟。
我和我的同事都对此没有任何解释,Google 也没有提供帮助,因此我非常感谢您的帮助。
发现问题:
或者至少是其中的一部分。它似乎是由 GC 压力引起的,我已经知道如何在应用程序中减少它。我仍然不知道为什么 SpinWait 有时会导致线程阻塞,但我只是不使用它。
这个问题被标记为重复,Stack Overflow 告诉我编辑它以解释原因,但老实说,如果你甚至费心阅读标题,这很明显。
【问题讨论】:
-
编写
ToArray的基本实现并将您的诊断Stopwatch检查放入其中。如果您发现缓冲区数组分配占用了大部分执行时间,则表明 GC 压力或可能是整体系统负载问题。您可以使用the actual ToList method source 作为起点,如果需要,可以通过将Array.Copy替换为for循环来进一步增加粒度。 -
我重新打开了这个问题,因为它显然不是 stackoverflow.com/questions/1147497/… 的重复项(它只是问,“我听说 ToArray 很慢;是这样吗?”)
标签: c# multithreading performance blocking toarray