当前位置: 首页 > 编程语言 > C#

PlinqStatementDeadlockedinStaticConstructor分享

时间:2023-04-10 16:48:13 C#

PlinqStatementDeadlockedinStaticConstructor我遇到过这样的情况,静态构造函数中的以下plinq语句死锁:staticvoidMain(string[]args){newBlah();}classBlah{staticBlah(){Enumerable.Range(1,10000).AsParallel().Select(n=>n*3).ToList();它只发生在构造函数是静态的时候。请有人向我解释一下。它是TPL错误吗?翻译器?我?从静态构造函数调用线程代码通常是危险的。为确保静态构造函数只执行一次,CLR在锁下执行静态构造函数。如果运行静态构造函数的线程在辅助线程上等待,那么由于某种原因辅助线程也可能需要CLR内在锁,程序就会死锁。下面是一个更简单的代码示例来演示该问题:usingSystem.Threading;classBlah{staticvoidMain(){/*不会运行,因为静态构造函数死锁了。*/}staticBlah(){线程thread=newThread(ThreadBody);线程。开始();线程.加入();}staticvoidThreadBody(){}}ECMACLI规范的第10.5.3.3节“竞争和死锁”保证了以下内容:初始化程序调用的一些代码(直接或间接)显式调用阻塞操作,否则单独的类型初始化不应该造成僵局。因此,如果静态构造函数中的操作不阻塞线程,则类型初始值设定项(即静态构造函数)不会死锁。如果静态构造函数阻塞,则存在死锁的风险。虽然已经解释了您不想在静态构造函数中进行线程处理的原因,但我想我要补充一点,“正确”的方法是使用静态Lazy。它也更有效率,因为生成这些资源的工作将在实际需要资源之前确定。classBlah{//提供工厂方法来生成数字,但实际生成将被推迟privatestaticLazy>MyMagicNumbers=newLazy>(Blah.GenerateMagicNumbers);publicvoidDoSomethingWithMagicNumbers(){//调用Lazy.Value将同步所有调用线程,直到值最初从工厂生成ListmagicNumbers=Blah.MyMagicNumbers.Value;//...在这里做点什么...}privateListGenerateMagicNumbers(){returnEnumerable.Range(1,10000).AsParallel().Select(n=>n*3).ToList();对于它的价值,这个问题不会发生在Mono上:[mono]/tmp@dmcspar.cs[mono]/tmp@mono./par.exe结果MSIL?我不认为这是一个仅限库的问题,我很好奇:)比较IL有点混乱,所以我决定在两个平台上尝试两个二进制文件。嘿,我复活了我的旧WindowsVM只是为了测试这个:)在Mono上运行VS编译的二进制文件是没有问题的。您可以在Windows上试用2.10.1(http://www.go-mono.com/mono-downloads/download.html),只有77.4Mb?(我在linux2.11上使用自定义单声道,因此功能支持尚未完成)在平台上运行:MS.Net4.0Mono2.1x构建于:------------+-------------------------------------VisualStudio|死锁没有死锁|单开发|deadlock没有死锁我还注意到在Windows上运行时,CTRL-C能够打破锁。如果我发现更多,请发帖。更新2那么,即使在Windows上安装了VSExpress,安装Mono也能正常工作。安装单声道已在4分钟内完成并导致:C:\UsersSeth>"c:ProgramFiles(x86)Mono-2.10.1binmono.exe"ConsoleApplication2.exeC:\UsersSeth>没有死锁:)现在剩下的就是等待VSExpress安装(永远)并安装调试工具(未知)而不是出现裂缝(可能直到深夜)。再见,以上就是C#学习教程:Plinq语句死锁在静态构造函数中。分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处: