我有一系列长期运行的职能。我希望将它们包装在一个文件中,Task
以便可以同时运行所有文件,而不是等待每个文件依次完成。
方法调用,所有相关的字段值以及方法和属性都存在于静态类中。
我遇到一个问题,其中静态类构造函数无法完成,因为当我将方法包装在中时,它会挂起Task.Run
。
符合必要的最小,完整和可验证的示例要求...
using System;
using System.Linq;
using System.Threading.Tasks;
namespace MCVEAsyncHang
{
class Program
{
private static readonly string[] _foo;
static Program()
{
_foo = Task.WhenAll(Task.Run(new Func<string>(One))).Result;
}
private static string One()
{
return "Foo";
}
private static void Print()
{
Console.WriteLine(
_foo.Aggregate((total, current) =>
total + string.Format("{0}{1}", Environment.NewLine, current)));
}
static void Main(string[] args)
{
Print();
Console.WriteLine("Done");
Console.ReadLine();
}
}
}
我知道我可以创建其他方法并调用该方法(如果必须的话,我会这样做),但如果可能的话,我宁愿将其保留在静态类构造函数中。
您的任务(将在另一个线程中运行)需要调用_one
。Program
在初始化您的类型之前,该方法无法执行。
任务的线程将看到该Program
类型已在主线程中初始化,因此将阻塞直到该线程完成对类型的初始化。不幸的是,这不会发生-因为类型初始化器将阻塞直到您的任务完成。僵局。
基本上,您应该避免在静态构造函数中做过多的工作。启动任务肯定感觉太麻烦了。在这种情况下,僵局是显而易见的,但在其他情况下,它可能更加微妙。(在此之前,我花了数小时来调试类型初始化器循环,这真的非常好玩。那是单线程代码-我害怕认为在多线程环境中会很痛苦。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句