我试图将线程添加到我所拥有的静态类中,并遇到了一堆问题。我阅读了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());
}
}
}
答案 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之间的区别。
注意,我正在描述当前编译器的行为。此行为可以在相关规范中找到,也可以是实现定义的。我没看过。