Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Plinq语句在静态构造函数中陷入僵局_C#_.net_Task Parallel Library_Plinq - Fatal编程技术网

C# Plinq语句在静态构造函数中陷入僵局

C# Plinq语句在静态构造函数中陷入僵局,c#,.net,task-parallel-library,plinq,C#,.net,Task Parallel Library,Plinq,我遇到这样的情况,静态构造函数中的以下plinq语句陷入僵局: static void Main(string[] args) { new Blah(); } class Blah { static Blah() { Enumerable.Range(1, 10000) .AsParallel() .Select(n => n * 3) .ToList(); }

我遇到这样的情况,静态构造函数中的以下plinq语句陷入僵局:

static void Main(string[] args)
{
    new Blah();
}

class Blah
{
     static Blah()
     {
         Enumerable.Range(1, 10000)
            .AsParallel()
            .Select(n => n * 3)
            .ToList();
     }
}
它仅在构造函数是静态的情况下发生。 有人能给我解释一下吗


是第三方物流错误吗?编译程序?Me?

不管它值多少钱,Mono上不会出现这个问题:

[mono] /tmp @ dmcs par.cs 
[mono] /tmp @ mono ./par.exe 

您是否有windows编译的二进制文件,以便我可以比较生成的MSIL?我不相信这是一个图书馆唯一的问题,我很好奇:)


比较IL有点混乱,所以我决定在两种平台上都试用这两种二进制文件。 呵呵,我恢复了我的旧Windows虚拟机只是为了测试这个:)

在Mono上运行VS编译的二进制文件没有问题。您可以使用2.10.1在windows上试用它(http://www.go-mono.com/mono-downloads/download.html),只有77.4Mb:)

(我在linux上使用了定制的mono 2.11,因此功能支持可能还没有完成)

我还注意到,在windows上运行时,CTRL-C可以打破锁定。 如果我找到更多的话,我会发帖的


更新2 好吧,安装Mono会绕着在windows上安装VSExpress转一圈。安装mono在4分钟内完成,结果是:

C:\Users\Seth>"c:\Program Files (x86)\Mono-2.10.1\bin\mono.exe" ConsoleApplication2.exe
C:\Users\Seth>

没有死锁:)现在剩下的就是等待VSExpress安装(永远)和所有调试工具(未知),然后破解它(可能直到深夜)。CU稍后

从静态构造函数调用线程代码通常是危险的。为了确保静态构造函数只执行一次,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() { }
}
第10.5.3.3节“竞争和死锁”保证以下内容:

除非某些代码 从类型初始值设定项(直接或间接)显式调用 调用阻塞操作


因此,类型初始值设定项(即静态构造函数)不会死锁,前提是静态构造函数中的任何操作都不会阻塞线程。如果静态构造函数真的阻塞了,它就有死锁的风险。

虽然已经解释了为什么您不想在静态构造函数中执行线程工作,但我想我应该补充一点,这样做的“正确”方法是使用静态构造函数。这也更有效,因为在实际需要这些资源之前,生成这些资源的工作将被取消

class Blah
{
    // Supply factory method to generate the numbers, but actual generation will be deferred
    private static Lazy<List<int>> MyMagicNumbers = new Lazy<List<int>>(Blah.GenerateMagicNumbers);

    public void DoSomethingWithMagicNumbers()
    {
        // Call to Lazy<T>.Value will synchronize any calling threads until value is initially generated from the factory
        List<int> magicNumbers = Blah.MyMagicNumbers.Value;

        // ... do something here ...
    }

    private List<int> GenerateMagicNumbers()
    {
        return Enumerable.Range(1, 10000)
                          .AsParallel()
                          .Select(n => n * 3)
                          .ToList();
    }
}
class废话
{
//提供工厂方法生成数字,但实际生成将延迟
私有静态惰性MyMagicNumbers=新惰性(Blah.GenerateMagicNumbers);
公共无效DoSomethingWithMagicNumber()
{
//对Lazy.Value的调用将同步所有调用线程,直到最初从工厂生成值为止
List magicNumbers=Blah.MyMagicNumbers.Value;
//…在这里做点什么。。。
}
私有列表生成器magicnumbers()
{
返回可枚举范围(11000)
.天冬酰胺()
.选择(n=>n*3)
.ToList();
}
}

您是否有windows编译的二进制文件,以便我可以比较生成的MSIL?我不相信这是一个图书馆唯一的问题,我很好奇:)你可以从这里下载代码和二进制文件:这里是一个windows二进制文件:我暂时放弃。无法在全新(从不运行:)Win7_64虚拟机上运行VSExpress。安装service pack失败(?!),因此,唉,今天我没有注意到WinDbg。感谢您的辛勤工作。这似乎是TPLForWindows实现中的一个错误。如果死锁是一种预期行为,我想知道为什么它不会在mono中发生。他们不是锁定了静态构造函数吗?这是一个很好的观点。谢谢你的回答。这只是一些不直观的东西。至少如果它以某种方式抛出了异常。。。
class Blah
{
    // Supply factory method to generate the numbers, but actual generation will be deferred
    private static Lazy<List<int>> MyMagicNumbers = new Lazy<List<int>>(Blah.GenerateMagicNumbers);

    public void DoSomethingWithMagicNumbers()
    {
        // Call to Lazy<T>.Value will synchronize any calling threads until value is initially generated from the factory
        List<int> magicNumbers = Blah.MyMagicNumbers.Value;

        // ... do something here ...
    }

    private List<int> GenerateMagicNumbers()
    {
        return Enumerable.Range(1, 10000)
                          .AsParallel()
                          .Select(n => n * 3)
                          .ToList();
    }
}