我有一系列长时间运行的功能。我想将它们包装在Task
中,以便我可以同时运行所有这些,而不是等待每一个顺序完成。
方法调用,静态类中存在所有相关的字段值和方法及属性。
我遇到一个问题,其中静态类构造函数无法完成,因为当我用Task.Run
包装方法时它就会挂起。
符合必要的Mininmal, Complete and Verifiable示例要求......
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();
}
}
}
我知道我可以创建一些其他方法并调用它(如果必须的话,我会这样做),但如果可能的话,我宁愿将它保留在静态类构造函数中。
答案 0 :(得分:8)
您的任务将在另一个线程中运行,需要调用if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject();
}
}
。该方法无法执行,直到您的_one
类型已初始化为止。
任务的线程将看到Program
类型已经已在主线程中初始化,因此将阻塞,直到该线程完成初始化类型。不幸的是,这不会发生 - 因为类型初始化程序将阻塞,直到您的任务完成。死锁。
基本上,你应该避免在静态构造函数中做太多工作。启动任务肯定感觉太多了。在这种情况下,死锁是显而易见的,但在其他情况下,它可能会更加微妙。 (在此之前我已经花了小时调试类型初始化程序循环,它真的,真的不好玩。那就是单一=线程代码 - 我不敢想它会有多痛苦在多线程环境中。)