Параллельный вызов с 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. Это избыточные потоки, которые будут заблокированы в ожидании завершения ввода-вывода.

Другие вопросы по тегам