Параллельный вызов с AwaitAsync в блокировке WebApi
У меня есть операция webApi, которая выполняет 2 операции в || который внутренне вызывает HttpClient sendAsync. Если я применяю отладчики и выполняю вызов, он работает и возвращается. Если я удаляю отладчики, оба асинхронных вызова все еще работают (проверено в Fiddler), но вызывающая сторона операции WebApi не получает никакого ответа (используя плагин AdvanceRest chrome). Из других потоков, возможно, я не использую async/await правильно и связан с ASP.NET synchronizationContext
//**WEB API Controller***
class SomeController
{
public HttpResponseMessage Get()
{
Client someClient = new Client();
aResponse = new aResponse();
bResponse = new bResponse();
Parallel.Invoke(
() => {aResponse = someClient.a()},
() => {bResponse = someClient.b()});
var response = {a=aResponse, b=bResponse};
return Response.Create(OK, response}
}
class SomeClient
{
AResponse a()
{
var clientResponse = ClientMgr.Execute("url");
return new AResponse {HttpClientResponse = clientResponse.Result}
}
BResponse b()
{
var clientResponse = ClientMgr.Execute("url");
return new BResponse {HttpClientResponse = clientResponse.Result}
}
}
//Utility CLASS
public class ClientMgr
{
public static async Task<HttpResponseMessage> Execute(string url)
{
request = new HttpRequestMessage();
//....request fill
HttpClient client = new HttpClient();
var response = await client.SendAsync(request);
client.dispose();
return response;
}
}
public class AResponse
{
HttpResponseMessage HttpClientResponse {get;set;}
// Some other properties....
}
Почему операция возвращает ответ, когда я использую точки останова, но как только я их удаляю, она не возвращает ответ?
1 ответ
Ваша проблема (кроме того факта, что опубликованный вами код не компилируется) заключается в том, что во время отладки асинхронные операции фактически завершаются. Когда вы не отлаживаете, они не делают, и это возвращает Task<YourResponse>
, а не фактический результат Task
,
Чтобы это работало, пометьте свой метод как async
и использовать Task.WhenAll
асинхронно ждать обеих задач:
[HttpGet]
public async Task<HttpResponseMessage> GetAsync()
{
Client someClient = new Client();
var aTask = someClient.AAsync();
var bTask = someClient.BAsync();
await Task.WhenAll(aTask, bTask);
var response = { a = aTask.Result, b = bTask.Result };
return Response.Create(OK, response}
}
Примечание: вам не нужно использовать Paralle.Invoke
когда у вас есть операции, связанные с IO. Это избыточные потоки, которые будут заблокированы в ожидании завершения ввода-вывода.