Я развиваюсь ASP.Net Web Api
.Я использую async
методы для запуска асинхронного кода при необходимости.Также у меня есть несколько конкретных случаев, когда мне нужно заблокировать эти async
методы, чтобы получить результат.Поскольку блокировка асинхронных методов в потоке ASP.Net Request
вызывает тупик (объяснение, почему можно найти здесь ), я решил заблокировать асинхронные методы в отдельной задаче, используя 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 в этом примере).Видимо, это не так.У меня есть вопросы:
- Как это возможно?
- Как я могу убедиться, что Задача всегда будет выполняться в потоке
ThreadPool
, а не в вызывающем ASP.Net Request
thread?
Также обратите внимание, что из-за некоторых деталей, которые я не хочу здесь объяснять, я ДОЛЖЕН блокировать асинхронные методы, и нет способа сделать мои методы асинхронными вплоть до самого верха.