-1

In my program, i'm making a request, and I log the request and the response. But using the ConfigureAwait(false), may loses the context of my "logger" object, which is logging the request in one file, and the response in another file.

try
{
    logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
    serializedResponse = await httpHandler.PostAsync<string>
                        (tokenParameters.Endpoint, payloadJson, options, cts.Token)
                        .ConfigureAwait(false);
}
catch (TaskCanceledException)
{
    throw new TokenTimeoutException();
}
catch (Exception ex)
{
    logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
    throw;
}

Any Idea why this is happening? Or what to do to avoid it?

By removing the ConfigureAwait(false) I may have TimeOut problems, so that is not an option.

Ayman
  • 580
  • 9
  • 27
  • 4
    Ehmm.... I thought that that behavior is by design.... – Stefan Oct 08 '18 at 17:52
  • @PoulBak Why in the world would you explicitly not run the continuation in the current context only to then explicitly schedule the continuation to run in that context? – Servy Oct 08 '18 at 19:51
  • 1
    `By removing the ConfigureAwait(false) I may have TimeOut problems` Are you waiting synchronously on a task somewhere? If so, that's the issue you should be fixing – Kevin Gosse Oct 09 '18 at 06:49

1 Answers1

1

That's by design behavior, so you must ask yourself: "Am I doing this the right way?"

There are various way's to overcome that problem. If you want a loggable fire-and-forget async call, you can wrap it in a call like this. But beware, the task runs probably on a different context, so you might not have access to typical context-bound variables, like your current HttpContext (and stuff like that).

Task.Run(async () => 
{
    try
    {
        logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
        serializedResponse = await httpHandler.PostAsync<string>
                                 (tokenParameters.Endpoint, payloadJson, options, cts.Token);
    }
    catch (TaskCanceledException)
    {
        throw new TokenTimeoutException();
    }
    catch (Exception ex)
    {
        logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
        throw;
    }
}).ConfigureAwait(false);


Or even better: wrap it in a function
async Task DoStuff()
{
    try
    {
        logger.VerboseRequest(tokenParameters.Endpoint, payloadJson, options);
        serializedResponse = await httpHandler.PostAsync<string>
                                 (tokenParameters.Endpoint, payloadJson, options, cts.Token);
    }
    catch (TaskCanceledException)
    {
        throw new TokenTimeoutException();
    }
    catch (Exception ex)
    {
        logger.Error(String.Format("Error when posting to Endpoint: {0}",ex.Message));
        throw;
    }
}

And where your current code is:

async Task WhereYouAreDoingStuff()
{
    DoStuff().ConfigureAwait(false);
}
Stefan
  • 17,448
  • 11
  • 60
  • 79
  • First, I'm sorry about the bad formulated question. I'm new at async/await calls and I don't understand it very well. I Tried the approach you suggested, but I'm still getting a deadlock, if I don't use the configureAwait(False) in the HttpHandler call – Fernando Augusto Stavro Duarte Oct 09 '18 at 14:00
  • @FernandoAugustoStavroDuarte: No worries; Do you use `.Wait()` or `.Result` somewhere? If you can show more of your code we'll get more information about the context. About async/await and deadlocks; this might help you: https://stackoverflow.com/questions/13140523/await-vs-task-wait-deadlock#13140963 – Stefan Oct 10 '18 at 07:23
  • Hi! I still haven't found the problem, but i've talked to my boss, and this is an expected behaviour, defined with the client. Thanks for your Help! – Fernando Augusto Stavro Duarte Oct 10 '18 at 19:24