3

我试图将线程添加到我拥有的静态类中,但遇到了一堆问题。我阅读了这个线程和它链接到的博客文章,我想我明白发生了什么。但我不明白为什么 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()); 
        }
    }
}
4

1 回答 1

7

以下确实会导致死锁:

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

有什么不同?

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

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

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

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

于 2013-04-02T21:35:34.120 回答