I'm trying to use await/async in order to make some synchronous code asynchronous. For example, this works and unblocks the UI thread:
private async void button1_Click(object sender, EventArgs e)
{
    var task = DoRequestAsync();
    textBox1.Text = "starting async task";
    var text = await task;
    textBox1.Text = text;
}
private async Task<string> DoRequestAsync()
{
    try
    {
        var client = new HttpClient();
        client.Timeout = new TimeSpan(0, 0, 0, 5);
        await client.GetAsync("http://123.123.123.123"); // force a timeout exception
    }
    catch (Exception e)
    {
    }
    return "done!";
}
But this doesn't, and will hang the UI thread:
private async void button1_Click(object sender, EventArgs e)
{
    var task = DoRequestAsync();
    textBox1.Text = "starting async task";
    var text = await task;
    textBox1.Text = text;
}
private async Task<string> DoRequestAsync()
{
    try
    {
        var request = WebRequest.Create("http://123.123.123.123");
        request.Timeout = 5000;
        request.GetResponse(); // force a timeout exception
    }
    catch (Exception e)
    {
    }
    return "done!";
}
I'm trying to understand why this is the case. I was under the impression that var task = DoRequestAsync() will create a new thread and run everything in the method asynchronously, but that appears to not be the case.
I can use this to make it work:
await Task.Run(() => {
    var request = WebRequest.Create("http://123.123.123.123");
    request.Timeout = 5000;
    request.GetResponse();
});
But this seems a bit hacky and I'm not sure if it's the right solution to this issue. Does anybody know how I can just run a bunch of synchronous code in an asynchronous way using Tasks and async/await?
That's the right solution. WebRequest.GetResponse is not an async method therefore it does not return a Task. It cannot run asynchronously. 
Actually, what you have there is the most correct and shorthand solution you can get (with Task.Run). 
I was under the impression that var task = DoRequestAsync() will create a new thread and run everything in the method asynchronously, but that appears to not be the case.
It's not magic. In order for it to run asynchronously, a new Task (not thread) must be created in your async method or it must await on one or more methods)that return either Task, Task<T> or void (this is for event handlers).
Your last statement in the method return "done!"; just returns a completed Task<string> with result "done". 
As a side note, this is why HttpClient is becoming the de facto class HTTP requests, especially for interoperating with web APIs but also for general purpose GETs/POSTs/etc: it has async support.
Tasks also have support to wrap Begin*/End* functions (conforming to the former asynchronous programming model - APM). You can also do:
try
{
    var request = WebRequest.Create("http://123.123.123.123");
    request.Timeout = 5000;
    await Task.Factory.FromAsync(request.BeginGetResponse(), request.EndGetResponse, null); // force a timeout exception
}
catch (Exception e)
{
    //TODO handle exception here
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With