Асинхронный шаблон здесь сохраняется?
Нет.Нет ничего волшебного в использовании await
для задачи.Вместо этого рассмотрите , завершена ли задача .Вызов task.Result
заблокирует вызывающий поток, пока task
не завершится.Выполнение await task
будет асинхронно ждать, пока не завершится task
.
Так что в этом коде Result
не будет блокировать:
static async Task<int> AwaitForResult(Task<int> task)
{
// Task may not yet be complete here.
await task;
// At this point, task is complete.
// Since task is complete, Result does not block.
return task.Result;
}
Но это полностью отличается от этого кода:
var result = AwaitForResult(addNumbersTask).Result;
// Equivalent to:
var task = AwaitForResult(addNumbersTask);
var result = task.Result;
Задание, возвращаемое с AwaitForResult
, может быть не завершено, поскольку оно никогда не было await
ред.А если он не завершен, то Result
заблокируется.
Попытка передачи кода IL для прокси-класса, который должен обрабатывать асинхронные вызовы, но я не хочу генерировать асинхронный конечный автоматв ил.Поэтому я решил, что мог бы делегировать фактическую часть «ожидание» помощнику за пределами IL.
Пробовали ли вы API-интерфейсы Roslyn?Я нахожу их намного более удобными, чем IL emit.
Если ваш прокси-сервер является просто промежуточным, то вы можете просто вернуть внутреннюю задачу напрямую:
// This class 100% generated via reflection emit
class Proxy : IService
{
private readonly IService _actual;
public Proxy(IService actual) => _actual = actual;
public Task<int> AddAsync(int a, int b) => _actual.AddAsync(a, b);
}
Но если вы хотитедобавьте много реальной логики, тогда я бы рекомендовал использовать Roslyn для генерации конечного автомата async
.