Benedikt Benedikt - 2 months ago 11
C# Question

Is async code that easy?

I am working on a C# Hue application, I am creating the api calls myself for the learning experience. Since Hue consists of many network calls i wanted to also provide an async method for every sync method i create. I wrote some lines of code and thought to myself "This can't possibly be so easy", so now I'm here and wanted to ask if this is a good way to implement async functions? Also any other optimizations to my code are appreciated.

using System.IO;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace SharpHue
{
public class HueUtilities
{
const string DISCOVERY_URI = "http://www.meethue.com/api/nupnp";

public struct DiscoveryElement
{
[JsonProperty("id")]
public string ID;
[JsonProperty("internalipaddress")]
public string Address;
}

public static DiscoveryElement[] DiscoverBridges()
{
string data = "[]";
var request = WebRequest.CreateHttp(DISCOVERY_URI);
try
{
var response = request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
data = streamReader.ReadToEnd();
streamReader.Close();
response.Close();
}
return JsonConvert.DeserializeObject<DiscoveryElement[]>(data);
}
catch (Exception ex)
{
throw ex;
}
}

public static async Task<DiscoveryElement[]> DiscoverBridgesAsync()
{
return await Task.Run(() => DiscoverBridges());
}
}
}

Answer

Almost. But you should avoid Task.Run when there are true async alternatives. In your case that means replacing WebRequest class with HttpClient and call your code like this:

public static async Task<DiscoveryElement[]> DiscoverBridgesAsync() 
{
    using (var client = new HttpClient())
    {
        var result = await client.GetAsync(DISCOVERY_URI);
        return await result.Content.ReadAsAsync<DiscoveryElement[]>();     
    }
}

As you can see there is no more use for the method that wrapped the synchronous call to an async call. It's now truly async/await compliant.

warning There might be some compile errors but should work.

More info: http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

And please, read this: http://www.ben-morris.com/why-you-shouldnt-create-asynchronous-wrappers-with-task-run/