Bor*_*itz 8 .net c# plinq task-parallel-library
我遇到了这种情况,其中静态构造函数中的以下plinq语句被死锁:
static void Main(string[] args)
{
new Blah();
}
class Blah
{
static Blah()
{
Enumerable.Range(1, 10000)
.AsParallel()
.Select(n => n * 3)
.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
它仅在构造函数是静态时发生.请有人向我解释一下.
是TPL错误吗?编译器?我?
从静态构造函数调用线程代码通常很危险.为了确保静态构造函数只执行一次,CLR在锁定下执行静态构造函数.如果运行静态构造函数的线程在辅助线程上等待,则由于某种原因,辅助线程也可能需要CLR内部锁,并且程序将死锁.
这是一个更简单的代码示例,演示了这个问题:
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() { }
}
Run Code Online (Sandbox Code Playgroud)
第10.5.3.3节ECMA CLI规范的 "种族和死锁" 保证以下内容:
除非从类型初始化程序(直接或间接)调用的某些代码显式调用阻塞操作,否则单独的类型初始化不应创建死锁.
因此,只要静态构造函数中的操作没有阻塞线程,类型初始化器(即静态构造函数)就不会死锁.如果静态构造函数阻塞,则存在死锁的风险.