0

I'm sending a request from a service and explicitly calling the logout API to free resources but I'm encountering the error in the title. I'm using Task.Run() to prevent deadlocks.

Currently this is my code:

        var baseAddress = new Uri(baseServiceUrl);
        var cookieContainer = new CookieContainer();
        using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
        using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
        {
            client.Timeout = TimeSpan.FromSeconds(3600);
            client.DefaultRequestHeaders.Authorization = authentication;
            var requestUrl = GenerateServiceRequestUrl();
            using (var response = Task.Run(() => client.GetAsync(requestUrl)).GetAwaiter().GetResult())
            {
                //call logout explicity
                using (Task.Run(() => client.GetAsync(baseServiceUrl + LogoutUrl).GetAwaiter().GetResult())) { }

                return new MyServiceResponse(response, getContent);
            }
        }

The error is from this line of code calling the logout explicitly:

using (Task.Run(() => client.GetAsync(_baseUrl + LogoutUrl).GetAwaiter().GetResult())) { }

However when I try to change it to the code below, the error is gone:

using (client.GetAsync(baseServiceUrl + LogoutUrl).Result) { }

My question is that is there a way to use Task.Run() for the logout call?

hisoka21
  • 855
  • 1
  • 12
  • 21
  • 1
    Why are you *disposing* the *task* again? Don't do that. Instead of Task.Run, use `await` – TheGeneral Jul 28 '20 at 05:41
  • 1
    There’s no need for Task.Run against code that is already async. Particularly for I/O –  Jul 28 '20 at 05:41
  • 1
    **1)** you should probably be using `IHttpClientFactory` and declare your *handler* in the implementation a named client **2)** This method should marked as `async`. **3)** You should not be trying to *offload* IO calls to `Task.Run` **4)** you should never be calling `GetAwaiter().GetResult()` ever! (unless you know what you are doing, and even then its suspicious) **5)** there should be no need to *dispose* a *task* even if you are calling `Task.Run` (which you shouldn't be) – TheGeneral Jul 28 '20 at 05:47
  • 1
    **6)** if you were doing all the above, there would be no need to call `using` on anything here unless you had a disposable content stream (though it wouldn't hurt and is good practice) **7)** definitely don't call `using` on a raw `HttpClient` Instance – TheGeneral Jul 28 '20 at 05:55
  • @TheGeneral do you mean for both usage of Task.Run(), I should just use 'await client.GetAsync(requestUri).Result? – hisoka21 Jul 28 '20 at 05:58
  • 1
    **8)** don't call `Result`... your code would be E.g `var response = await client.GetAsync(requestUri);` – TheGeneral Jul 28 '20 at 05:59
  • 1
    This might help https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ or https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests – TheGeneral Jul 28 '20 at 06:07
  • Take a step back and tell us _why_ you added the using in `using (Task.Run(() => client.GetAsync(baseServiceUrl + LogoutUrl).GetAwaiter().GetResult())) { }`. What are you trying to achieve with it? – mjwills Jul 28 '20 at 06:11
  • @TheGeneral thank you! I'll update my implementation. Thank you again for pointing me to the right direction! – hisoka21 Jul 28 '20 at 06:14
  • @TheGeneral yes I use the Task.Run to avoid deadlocks. I think I saw it in one of the posts here in stack – hisoka21 Jul 28 '20 at 06:18
  • @mjwills sorry my bad. Maybe it just became a habit (bad one?). You mean 'using' was not necessary for Task.Run?. – hisoka21 Jul 28 '20 at 06:27
  • 1
    https://stackoverflow.com/questions/3734280/is-it-considered-acceptable-to-not-call-dispose-on-a-tpl-task-object – mjwills Jul 28 '20 at 06:36

0 Answers0