我正在开发ASP.Net Web Api
。我在需要时使用async
方法来运行一些异步代码。当需要阻塞这些async
方法以获取结果时,我还有一些特定的情况。由于在ASP.Net Request
线程中阻止异步方法会导致死锁(解释为什么可以找到here),所以我决定使用Task.Run
在单独的任务中阻止异步方法。考虑以下示例:
public class TestController : ApiController
{
// This method must be synchronous
public void Test()
{
Debug.WriteLine($"Main Thread {Thread.CurrentThread.ManagedThreadId}");
// I must use a Task here because otherwise I will have to block async code which will cause a deadlock
var task = Task.Run(() =>
{
Debug.WriteLine($"Child Thread {Thread.CurrentThread.ManagedThreadId}");
SomeAsynchronousWork().GetAwaiter().GetResult();
});
task.GetAwaiter().GetResult();
}
public async Task SomeAsynchronousWork()
{
// some work that must be done asynchronously
}
}
现在有时运行Test
方法时,我可以看到这种调试输出
Main Thread 5
Child Thread 5
这意味着该任务在导致死锁的同一线程上运行。这对我来说很奇怪,因为据我所知Task.Run
应该在ThreadPool
线程上运行任务,并且它永远不能成为主线程(在本示例中为ASP.Net Request线程)。显然并非如此。我有问题:
ThreadPool
线程上运行而不在调用的ASP.Net Request
线程上运行?还要注意,由于某些细节我不想在这里解释,因此我必须阻止异步方法,并且没有办法使我的方法一直到顶部都是异步的。