繁体   English   中英

未从任务委托调用方法

[英]Method not gets called from task delegate

我正在尝试使用System.Threading.Tasks.Task类实现并行处理。 奇怪的是,任务委托的执行在第一个方法调用时停止。 我在下面的示例代码中进行了编码,以重新创建问题。

using System;
using System.Threading.Tasks;

namespace TestApp
{
    public static class TestClass
    {
        static TestClass()
        {
            var tasks = new Task[Environment.ProcessorCount];
            for (int i = 0; i < Environment.ProcessorCount; i++)
            {
                var task = Task.Run(() =>
                {
                    Console.WriteLine("Start the Task " + i);

                    // Method Foo is not called. 
                    // Stack trace show a managed to native transition.
                    // Why? 
                    Foo(i);
                });
                tasks[i] = task;
            }

            Task.WaitAll(tasks);
            Console.WriteLine("Press eny key to exit");
            Console.ReadKey();
        }

        private static void Foo(int i)
        {
            Console.WriteLine("Foo in the Task " + i);
        }
    }
}

我调用方法TestClass.Bar()来调用TestClass的静态构造函数。 主线程按预期在Task.WaitAll(tasks)调用上等待并行任务。 但是它从未完成,因为任务本身被卡在Foo方法调用中。

卡住的任务之一的堆栈跟踪:

TestApp.exe!TestApp.TestClass..cctor.AnonymousMethod__0
[Managed to Native Transition]
TestApp.exe!TestApp.TestClass..cctor.AnonymousMethod__0() Line 18
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke()
mscorlib.dll!System.Threading.Tasks.Task.Execute()
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

有人可以建议为什么不调用Foo方法吗?

静态构造函数只能执行一次。 当您在类上调用任何方法时-静态构造函数必须执行(如果尚未执行),除非此刻已经在执行。 在这种情况下,第二个调用应等待静态构造函数完成。

您可以在静态构造函数中启动多个任务,然后使用Task.WaitAll阻止它们完成。

但是,每个任务还​​调用同一类的静态方法( Foo )。 每个此类调用都必须等待静态构造函数完成(因为此刻正在执行)。 但这永远不会发生,因为静态构造函数是通过等待任务完成而被阻塞的,而任务是等待静态构造函数完成而被阻塞的,所以您会遇到经典的死锁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM