Parallel For不会在静态构造函数中导致死锁吗?

Cut*_*ert 2 .net c# multithreading

我试图将线程添加到我所拥有的静态类中,并遇到了一堆问题.我读了这个帖子和它链接到的博客文章,我想我明白了发生了什么.但我无法弄清楚为什么Parallel For循环仍然像在这个例子中那样工作:

using System;
using System.Threading;
using System.Threading.Tasks; 

namespace ThreadingTest
{
    public static class TestClass
    {
        public static int AwesomeNum = 43; 

        static TestClass()
        {
            string[] x = { "deal", "witch", "panda"};

            //does not cause a deadlock? huh?
            Parallel.For(0, x.Length,  i =>
                {
                    Console.WriteLine(x[i]); 
                });

            //results in a deadlock
            //Parallel.Invoke(writesomething, writesomethingelse); 

            //results in deadlock
            Thread thread = new Thread(new ThreadStart(() =>
            {
                Console.WriteLine("there is a bear in my soup"); 
            }));

            thread.Start();
            thread.Join(); 
        }

        private static void writesomething()
        {
            Console.WriteLine("writing something"); 
        }

        private static void writesomethingelse()
        {
            Console.WriteLine("writing something else."); 
        }
    }
}


using System;

namespace ThreadingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(TestClass.AwesomeNum.ToString()); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*cob 7

以下确实会导致死锁:

Parallel.For(0, x.Length,  i => {
   Console.WriteLine(i); 
});
Run Code Online (Sandbox Code Playgroud)

有什么不同?

我上面写的lambda表达式被编译为一个方法TestClass.您在new Thread示例中编写的那个也是如此.

你在并行表达式中编写的lambda i => Console.WriteLine(x[i])被编译成一个不同的编译器生成的类,因为它捕获了x.所以要执行它需要静态初始化闭包类,但不是TestClass.

所以它与Parallelvs任何其他线程机制无关.它只是需要生成闭包对象的lambda和不生成闭包对象的lambda之间的区别.

注意,我正在描述当前编译器的行为.此行为可以在相关规范中找到,也可以是实现定义的.我没有看.

  • 封闭类如何实现的细节在C#规范中被称为实现细节. (2认同)