3

This is my HttpService class, it works fine. But it seems weird, the code in every function much the same. And I should write try/catch in every functions, espcially TaskCanceledException, if I do not catch it here, my application will terminate. Could some one give me some example about how to optimize the code?

[Export(typeof(IDataSource))]
public class HttpService : IDataSource
{
    HttpClient client = new HttpClient();
    public HttpService()
    {
        client.BaseAddress = new Uri("https://localhost:3721");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public void Initialize(CurrentUser currentUser)
    {
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
            Convert.ToBase64String(Encoding.UTF8.GetBytes(currentUser.Name + ":" + currentUser.Password)));
    }

    public async Task<IEnumerable<User>> getUsers()
    {
        try
        {
            var response = await client.GetAsync("api/User");
            //response.EnsureSuccessStatusCode(); // Throw on error code.
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<IEnumerable<User>>();
                return result;
            }
            else
            {
                return null;
            }
        }
        catch (Newtonsoft.Json.JsonException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (TaskCanceledException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        return null;
    }

    public async Task<IEnumerable<permission>> getPermission()
    {
        try
        {
            var response = await client.GetAsync("api/User");
            //response.EnsureSuccessStatusCode(); // Throw on error code.
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<IEnumerable<permission>>();
                return result;
            }
            else
            {
                return null;
            }
        }
        catch (Newtonsoft.Json.JsonException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (TaskCanceledException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        return null;
    }

    public async Task<CurrentUser> getCurrentUserInfo(User user)
    {
        try
        {
            var response = await client.GetAsync("api/User?name=" + user.Name);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<CurrentUser>();
                return result;
            }
            else
            {

                return null;
            }
        }
        catch (Newtonsoft.Json.JsonException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        catch (TaskCanceledException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        return null;
    }

}
4

2 回答 2

5

if I do not catch it here, my application will terminate.

no, that is simply not true; it is the code that invokes it also has the chance (and indeed, responsibility) to handle the errors. For example:

try {
    var permission = await getPermission();
    //...
} catch(Exception ex) {
    // log, whatever
}

Putting the exception handling in the most appropriate place will reduce this unnecessary code in your async methods. What you are currently doing is making your async methods pretend that nothing bad happened - that is not the best practice here.

于 2013-05-15T13:11:04.297 回答
3

免责声明:我无法编译此内容,因此您可能需要对其进行一些按摩。

我看到你唯一能做的就是做一个这样的方法:

public async Task<T> getAsync(string url)
{
    try
    {
        var response = await client.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            var result = await response.Content.ReadAsAsync<T>();
            return (T)result;
        }
        else
        {
            return null;
        }
    }
    catch (Newtonsoft.Json.JsonException ex)
    {
        Console.WriteLine(ex.ToString());
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine(ex.ToString());
    }
    catch (TaskCanceledException ex)
    {
        Console.WriteLine(ex.ToString());
    }
    return null;
}

然后你可以这样称呼它:

public async Task<IEnumerable<User>> getUsers()
{
    return await getAsync("api/User");
}

public async Task<IEnumerable<permission>> getPermission()
{
    return await getAsync("api/User");
}

public async Task<CurrentUser> getCurrentUserInfo(User user)
{
    return await getAsync("api/User?name=" + user.Name);
}
于 2013-05-15T13:09:05.937 回答