1

I am quite new to C#. I'm using the await keyword to invoke HttpClient's API.

static async Task<HttpResponseMessage> CreateChannel(string channelName)
{
    try
    {
        HttpClient client = new HttpClient();
        var req = new 
        {
            id= channelName
        };
        StringContent content = new StringContent(JsonConvert.SerializeObject(req).ToString(), Encoding.UTF8, "application/json");
        HttpResponseMessage response = await client.PostAsync("http://localhost:3000/channel", content);
        response.EnsureSuccessStatusCode();
        return response;
    }
    catch (Exception ex)
    {
       ...
        var view = new Dialog();
       ...
        var result = await DialogHost.Show(view);
        return null;
    }
}

private void initSocketIo(string channel)
{
    CreateChannel(channel).Wait();
    ...
    // after this method we init UI etc.
}

I have 2 problems which I can't seem to be able to solve

  1. After the client.PostAsync() method runs, my app just crashes. Simple as that. I understand it's because the main thread doesn't have anything else to process, but all the code above happens in the constructor code of MainWindow, so there is a lot more to do after the await
  2. The exception is never triggered. How do I ensure that my exception catch clause is invoked in client.PostAsync() throws an exception.

Any code suggestion that just works would do :).

Souvik Ghosh
  • 4,456
  • 13
  • 56
  • 78
victor
  • 1,626
  • 1
  • 14
  • 23
  • 2
    You are mixing blocking calls (`.Result`, `.Wait()`) with async calls which can lead to deadlocks. Make `initSocketTo` async. Also do not try to do async in the constructor. – Nkosi Sep 09 '17 at 17:08
  • 1
    Well ... what can I say. I asked what am I doing wrong and I get downvoted for doing it wrong. If you want to help, please post the correct way to do it. As I mentioned it's my first attempt at C# – victor Sep 11 '17 at 05:45
  • @Nkosi if I add async to `initSocketIo` it's the same thing. From my point of view I just want the app not to crash and catch HTTP exceptions. – victor Sep 11 '17 at 05:47
  • I did not down vote the post. adding async to initSocket does not make it async. You need to make the method return `Task`, then add async, and then use `await` on the other async method. – Nkosi Sep 11 '17 at 06:50
  • I know this is a little old, but I was having the same symptoms. What I found was my app was actually having a stack overflow occur on another thread (which forced the app to disappear). The timing just made it seam like it was the PostAsync since it took time. I figured this out by doing a desktop video capture of the app while it was running. – Matt Johnson Jan 05 '19 at 18:48

1 Answers1

2

You are mixing blocking calls (.Result, .Wait()) with async calls which can lead to deadlocks.

Make initSocketTo async.

private async Task initSocketIo(string channel) {
    var response = await CreateChannel(channel);
    ...
    // after this method we init UI etc.
}

Also do not try to do async in the constructor. Move the heavier processes later in the life cycle. You could even raise an event and handle that on another thread so as not to block the flow.

Nkosi
  • 235,767
  • 35
  • 427
  • 472