JsonHttpClient synchronous calls deadlocking

I’ve got a winforms client that is using the HttpJsonClient to make .Get calls to a web service. The client works fine using SS v5.7 and has been for years. Working on the next version and I’m using SS 5.11. Client code is basically same, but UI is deadlocking at the JsonHttpclient Get call response.

image

Did some googling and found this article on the httpClient: https://josef.codes/you-are-probably-still-using-httpclient-wrong-and-it-is-destabilizing-your-software/. Version 0 of that article says that you shouldn’t use sync calls with HTTP client, rather async all the way.

It looks like the synchronous calls in JsonHttpClient are using Task.Result.

   internal static class InternalExtensions
{
    public static T GetSyncResponse<T>(this Task<T> task)
    {
        try
        {
            return task.Result;
        }
        catch (Exception ex)
        {
            throw ex.UnwrapIfSingleException();
        }
    }

I’ve tried a few things to get around this while still using that client, but I still end up deadlocked. Just curious if anyone else has seen this. It looks like I just need to change to the JsonServiceClient since it uses the older web client for synchronous calls.

Thanks,
Brian

I swapped out the JsonHttpClient for the JsonServiceClient and the deadlock was fixed.

This is probably unique to windows forms when async needs to return back to the UI thread, but I think there needs to be some caution in the docs regarding using sync functions with the JsonHttpClient. Or better yet, an intellisense notation in the sync calls.

Right .NET’s HttpClient only supports async APIs so in order to implement IServiceClient sync APIs it needs to use “sync over async” which should be avoided where possible, I’ve updated the docs to mention this.

I’ve also updated the JsonHttpClient to use .ConfigureAwait(false) for all async calls and access the sync result with GetAwaiter().GetResult() (available in the latest v5.11.1 on MyGet) which should better help minimize deadlocks but should still be avoided.

That’s about all you can do at this point and that may have prevented the deadlock. Tempted to test that out to see if that made a difference, but I think I will stay away from that client unless I’m 100% async.

Thanks for all you do!

1 Like