方法未从任务委托中调用
Method not gets called from task delegate
我正在尝试使用 System.Threading.Tasks.Task
class 实现并行处理。奇怪的是,任务委托执行在第一次方法调用时停止。我编写了以下示例代码来重现问题。
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 方法没有被调用吗?
静态构造函数只能执行一次。当您在 class 上调用任何方法时 - 必须执行静态构造函数(如果尚未执行),除非它此时已经在执行。在这种情况下,第二次调用应该等到静态构造函数完成。
您在静态构造函数中启动多个任务,然后用 Task.WaitAll
阻止它们完成。
但是,每个任务也会调用相同class 的静态方法(Foo
)。每个这样的调用都必须等待静态构造函数完成(因为它正在执行)。但这永远不会发生,因为静态构造函数因等待任务完成而被阻塞,任务因等待静态构造函数完成而被阻塞,所以你有一个 classic 死锁。
我正在尝试使用 System.Threading.Tasks.Task
class 实现并行处理。奇怪的是,任务委托执行在第一次方法调用时停止。我编写了以下示例代码来重现问题。
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 方法没有被调用吗?
静态构造函数只能执行一次。当您在 class 上调用任何方法时 - 必须执行静态构造函数(如果尚未执行),除非它此时已经在执行。在这种情况下,第二次调用应该等到静态构造函数完成。
您在静态构造函数中启动多个任务,然后用 Task.WaitAll
阻止它们完成。
但是,每个任务也会调用相同class 的静态方法(Foo
)。每个这样的调用都必须等待静态构造函数完成(因为它正在执行)。但这永远不会发生,因为静态构造函数因等待任务完成而被阻塞,任务因等待静态构造函数完成而被阻塞,所以你有一个 classic 死锁。