PLINQ语句获取内静态构造函数陷入僵局 [英] Plinq statement gets deadlocked inside static constructor
问题描述
我碰到这个情况里面静态构造函数如下PLINQ语句获取陷入僵局:
I came across this situation where the following plinq statement inside static constructor gets deadlocked:
static void Main(string[] args)
{
new Blah();
}
class Blah
{
static Blah()
{
Enumerable.Range(1, 10000)
.AsParallel()
.Select(n => n * 3)
.ToList();
}
}
这种事只有当一个构造函数是静态的。 有人可以给我讲解一下吧。
It happens only when a constructor is static. Can someone explain this to me please.
它是TPL错误吗?编译器?我?
Is it TPL bug? Compiler? Me?
推荐答案
它通常是危险的,从静态构造函数调用线程code。为了确保静态构造只执行一次,在CLR执行下一个锁定的静态构造。如果运行静态构造的线程上一个辅助线程等待,有一种危险,即助手线程将需要在CLR-内部锁出于某种原因也和程序将死锁。
It is generally dangerous to call threading code from a static constructor. In order to ensure that the static constructor executes only once, the CLR executes the static constructor under a lock. If the thread running the static constructor waits on a helper thread, there is a risk that the helper thread is going to need the CLR-internal lock for some reason too, and the program will deadlock.
下面是一个简单的code示例,演示此问题:
Here is a simpler code sample that demonstrates the problem:
using System.Threading;
class Blah
{
static void Main() { /* Won’t run because the static constructor deadlocks. */ }
static Blah()
{
Thread thread = new Thread(ThreadBody);
thread.Start();
thread.Join();
}
static void ThreadBody() { }
}
第10.5.3.3竞赛和死锁的的 ECMA CLI规范保证如下:
类型单独初始化不得产生死锁,除非一些code 从类型初始化(直接或间接)明确要求 将调用阻塞操作。
Type initialization alone shall not create a deadlock unless some code called from a type initializer (directly or indirectly) explicitly invokes blocking operations.
所以,一个类型初始化(即静态构造函数)不会死锁,但在静态构造函数块没有操作的线程。如果静态构造函数做块,这样做可能会陷入僵局。
So, a type initializer (i.e., a static constructor) will not deadlock, provided that no operation in the static constructor blocks the thread. If the static constructor does block, it risks a deadlock.
这篇关于PLINQ语句获取内静态构造函数陷入僵局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!