我为什么要在这里锁?

Ign*_*cia 19 .net c# performance multithreading locking

请参阅以下并发性能分析,该分析表示并行foreach所完成的工作:

在此输入图像描述

在循环内部,每个线程从DB读取数据并对其进行处理.线程之间没有锁,因为每个处理不同的数据.

由于未知原因,看起来foreach的所有线程中都存在周期性锁定(请参阅黑色垂直矩形).如果您看到所选的锁定段(深红色段),您将看到堆栈显示在StockModel.Quotation构造函数处锁定的线程.那里的代码只构造了两个空列表!

我在某处读过这可能是由GC引起的所以我已经将垃圾收集更改为在服务器模式下运行:

<runtime>
    <gcServer enabled="true"/>
</runtime>
Run Code Online (Sandbox Code Playgroud)

我得到了一个小的改进(大约10% - 快15%),但我仍然有垂直锁定.

我还在所有数据库查询中添加了WITH(NOLOCK),因为我只读数据而没有任何区别.

有什么暗示这里发生的事情?

分析完成的计算机有8个核心.

编辑:启用Microsoft Symbol服务器后,所有线程都在wait_gor_gc_done或WaitUntilGCComplete等调用上被阻止.我认为启用GCServer我为每个线程都有一个GC,所以我会避免"垂直"锁定,但似乎并非如此.我错了吗?

第二个问题:由于机器没有内存压力(使用8个演出中的5个)有没有办法延迟GC执行或暂停它直到并行foreach结束(或将其配置为不经常发射)?

Kim*_*Kim 0

您可以尝试使用GCLatencyMode.LowLatency;此处查看相关问题:Prevent .NET Garbage collection for Short period period

我最近尝试过这个,但没有运气。当我在显示的表单上缓存图标大小的位图图像时,垃圾收集仍然被调用。对我有用的是使用 Ants 性能分析器和 Reflector 来查找导致 GC.Collect 的确切调用并解决它。