.NET线程如何等待不属于任何线程的syncblk?

red*_*dec 10 .net c# multithreading windbg monitor

我有一个来自我的应用程序的崩溃转储,显示一堆线程在syncblk上等待,而syncblk显示它没有拥有线程.怎么可能?我试图在测试应用程序中重现症状,我无法弄清楚产生该结果可能会发生什么....拥有自己的线程退出或死亡而不释放syncblk仍显示为拥有该对象,只是线程是"XXX"....我已经测试使用完全托管的优雅退出和硬线程终止通过pinvoke ....我测试了一堆不同的等待组合没有脉冲,不匹配进入和退出...什么都没有产生一个syncblk阻止线程,并没有显示所有者.....我的想法已经用完了

这是我试图复制的crashdump的输出:(注意索引#1236)

0:000> !syncblk
Index         SyncBlock MonitorHeld Recursion Owning Thread Info          SyncBlock Owner
 784 0000000004f12eb0            3         1 000000000508a460  32a8  68   00000001a0a20510
 966 0000000004f06928            1         1 00000000052c5da0  2380 114   00000001df3080f8
1085 0000000004f23088            1         1 00000000052c8080  496c 120   00000001a0325238
1144 0000000005160d20            1         1 00000000050968b0   d74  56   00000000ff61b570
1151 0000000004f0c2c8            1         1 000000000508d8b0  3f64  77   000000017f66dc20
1236 0000000004f0b4f8           16         0 0000000000000000     none    000000019f1ec5d8
1261 0000000004f0ffe8            1         1 0000000008f18fc0  446c  94   000000013f8e70b0
1306 0000000004f0e918            1         1 00000000052c91f0  406c 123   000000011f5936f8
1318 0000000004f0e528            3         1 0000000008f1d580  24d8 106   000000015fc73f28
1329 0000000004f0cc58            1         1 0000000005095740  2fbc  53   000000011f36d320
1332 0000000004f15b38            1         1 0000000008f16710  3804  87   000000019f964728
1387 0000000004f22350            1         1 0000000008f18420  5180  92   00000001a008ab08
1515 0000000004f1d5d0            1         1 00000000052c4c30  2b5c 111   00000000ffd3c068
1594 0000000004f19bc0            1         1 000000000508ea20  188c  80   000000012012c538
1660 0000000004f13608            1         1 00000000050892f0  32fc  65   00000001df800940
1682 00000000051608a0            1         1 000000000508c740  1d58  74   00000001bfa03d20
1746 0000000004f14e88            1         1 0000000008f1c9e0   e88 104   000000015f6fcd10
1883 0000000004f19938            1         1 0000000005092e90  27c4  46   00000000ff76d2b0
1886 0000000004f1b760            1         1 0000000008f19b60  2dd4  96   000000019fc07030
2036 0000000004f1ae10            1         1 0000000008f1be40  4f58 102   00000001dfcb9da8
2042 0000000004f12e68            1         1 00000000052c8c20  2300 122   000000015f6aaa98
2049 0000000004f1cda0            1         1 00000000052c9d90  1948 126   00000001df6fd688
2153 0000000004f16d88            1         1 0000000005094ba0  3f04  51   00000000ff677eb8
2262 0000000004f13de8            3         1 00000000052ca360   6fc 127   000000011fd7a450
2358 00000000050fc390            1         1 0000000009221280  3ca0 130   0000000120055ca0
-----------------------------
Total           2553
CCW             3
RCW             2
ComClassFactory 0
Free            1212
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 8

SyncBlock 000000019f1ec5d8是没有所有者的.也是唯一一个偶数的MonitorHeld人.由于MonitorHeld 为所有者增加1,每个服务员增加2,我猜测这是一个在转储之前就已经发布的资源,并且还没有授予新的所有者.不公平的资源在发布时向所有服务员发出信号并且服务员急于获得它(这种不公平的行为避免了车队锁定).在服务员安排和运行之前,第一个服务员抓住资源,就没有所有者.

另请参阅免费关键部分的高服务员计数可能表示锁定车队:

如果您正在调试应用程序中的性能问题,您可能会遇到一个非常奇怪的状态的关键部分:很多线程都在等待它,但是没有人拥有它!

...

这个状态意味着临界区的前一个所有者刚刚退出它并发出一个等待线程来接受它,但该线程还没有机会运行