Home > Net >  Deadlock when calling HttpClient.PostAsync
Deadlock when calling HttpClient.PostAsync

Time:10-01


I'm currently working on a project which consists of 2 application, one that's basically a rest server and a client. On the server part all seems to work fine but I have a deadlock when posting async in the client application.

The post handler in the server application is as for now (using Nancy):

Post("/", args =>
     {
         bool updated = false;

         string json = Request.Body.AsString();
         PostData data = JsonConvert.DeserializeObject<PostData>(json);

         int clientCode = data.ClientCode;
         bool started = data.Started;

         // TODO:
         // Update database
                    
        return updated;
    }
);

The deadlocking part of the client application is (I'm also adding the GET handling just for completeness, but it's working fine):

public async Task<string> Get()
{
    string actualRequest = $"{uri}/{request}";
    response = await client.GetAsync(actualRequest);
    response.EnsureSuccessStatusCode();

    result = await response.Content.ReadAsStringAsync();

    return result;
}

public async Task<string> Post(object data)
    {
    string json = JsonConvert.SerializeObject(data);
    StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

    response = await client.PostAsync(uri, content);
    result = await response.Content.ReadAsStringAsync();

    return result;
}

The small chunk of code used for testing is:

private static string response = "";
private static async Task TestPostConnection(RestClient client)
{
    PostData data = new PostData(1, true);
    response = await client.Post(data);
}

private static async Task TestGetConnection(RestClient client)
{
    client.Request = "id=1";
    response = await client.Get();
}

private static async Task InitializeClient()
{
    string ipAddress = "localhost";
    RestClient client = new RestClient("RestClient", new Uri($"http://{ipAddress}:{8080}"));

    await TestGetConnection(client); // OK
    await TestPostConnection(client);
}

Probably it's something stupid that I can't see because it's like 4 hours that I'm working on it :P

Thank in advantage!


Edit:
I'm using .net framework (4.7.2) and I'm not calling Result anywhere (just searched in Visual Studio for double check)

This is the Main method:

[STAThread]
static async Task Main()
{
    await InitializeClient(); // Call the async methods above

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ClientForm(response))
}

CodePudding user response:

I just solved the it.
The problem was the return type of the post handler in the server application

Post("/", args =>
{
        bool updated = false;

        string json = Request.Body.AsString();
        PostData data = JsonConvert.DeserializeObject<PostData>(json);

        int clientCode = data.ClientCode;
        bool started = data.Started;

        // TODO:
        // Update database

        return updated.ToString();
    }
);

The RestClient.Post() that I've implemented was expecting a string as a result (in fact the type of the method si (async) Task<string> but I was returning a bool).
Adding ToString() solved it.

Thanks all!

  • Related