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

时间:2013-04-02 21:21:54

标签: c# .net multithreading

我试图将线程添加到我所拥有的静态类中,并遇到了一堆问题。我阅读了this thread以及它链接到的博客文章,我想我明白了发生了什么。但我无法弄清楚为什么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()); 
        }
    }
}

1 个答案:

答案 0 :(得分:7)

以下 导致死锁:

Parallel.For(0, x.Length,  i => {
   Console.WriteLine(i); 
});

有什么区别?

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

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

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

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