在静态构造函数中调用时,用Task.Run(...)包装方法会挂起

我有一系列长期运行的职能。我希望将它们包装在一个文件中,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();
        }
    }
}

我知道我可以创建其他方法并调用该方法(如果必须的话,我会这样做),但如果可能的话,我宁愿将其保留在静态类构造函数中。

乔恩·斯基特

您的任务(将在另一个线程中运行)需要调用_oneProgram在初始化您的类型之前,该方法无法执行

任务的线程将看到该Program类型在主线程中初始化,因此将阻塞直到该线程完成对类型的初始化。不幸的是,这不会发生-因为类型初始化器将阻塞直到您的任务完成。僵局。

基本上,您应该避免在静态构造函数中做过多的工作。启动任务肯定感觉太麻烦了。在这种情况下,僵局是显而易见的,但在其他情况下,它可能更加微妙。(在此之前,我花了数小时来调试类型初始化器循环,这真的非常好玩。那是单线程代码-我害怕认为在多线程环境中会很痛苦。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 Task.Run 中包装 IO 绑定的异步方法

从java类中的构造函数调用的模拟静态方法

打字稿:在构造函数中调用静态方法

为什么调用task.run函数时我的异步函数挂起

为什么在调用非静态方法时会调用结构中的静态构造函数?

静态基础构造函数的设计模式,该模型在最终类中调用静态方法

Java包装器:覆盖在超级构造函数中调用的方法

公共静态Task Run(Func <Task>函数);

在构造函数中调用Dispose方法会引发异常或异常行为

静态调用扩展方法会抛出MissingMethodException

构造函数中的调用方法

为什么Mac OS控制台应用程序中对runloop.run的调用方法会创建其他线程?

为什么我不能从构造函数中调用静态方法?

用HtmlT包装的Run Reader,产生Html()

如果我调用静态方法,构造函数是否运行

构造函数调用的方法应该是静态的吗?

仅使用静态方法调用继承的类的构造函数

从类静态方法调用ES6类构造函数

静态构造方法与构造函数

从同步操作方法中调用异步方法:Task.Run或ConfigureAwaits(false)

如何从线程中调用与run()不同的方法

未调用 CommandLineRunner run() 方法

start() 不调用 run() 方法

Task.Run应该如何在VB.NET中调用异步方法?

线程构造函数如何才能直接接受run方法?

PyQt5 在类的方法中调用静态方法会弄乱方法代码的执行顺序

如果在构造函数中使用super调用重写的方法会发生什么

使用Task.Run调用异步方法似乎错误?

验证在Task.Run内部调用了Mock方法