2

我创建了一个使用async/返回对象的函数await。我想让函数通用,以便它可以返回我传入的任何对象。代码是样板文件,除了返回的对象。我希望能够调用 GetAsync 并让它返回正确的对象

public Patron getPatronById(string barcode)
{
    string uri = "patrons/find?barcode=" + barcode;
    Patron Patron =  GetAsync(uri).Result;
    return Patron;
}

private async Task<Patron> GetAsync(string uri)
{
    var client = GetHttpClient(uri);
    var content = await client.GetStringAsync(uri);
    JavaScriptSerializer ser = new JavaScriptSerializer();
    Patron Patron = ser.Deserialize<Patron>(content);
    return Patron;
}
4

2 回答 2

5

泛型方法呢?

private async Task<T> GetAsync<T>(string uri)
{
    var client = GetHttpClient(uri);
    var content = await client.GetStringAsync(uri);
    var serializer = new JavaScriptSerializer();
    var t = serializer.Deserialize<T>(content);
    return t;
}

通常,您应该将此方法放入另一个类中并制作它public,以便它可以被不同类中的方法使用。

关于调用此方法的方式,您可以尝试以下方法:

 // I capitalized the first letter of the method, 
 // since this is a very common convention in .NET
 public Patron GetPatronById(string barcode)
 {
     string uri = "patrons/find?barcode=" + barcode;
     var Patron =  GetAsync<Patron>(uri).Result;
     return Patron;
 }

注意:在上面的代码片段中,我假设您没有将其GetAsync移到另一个类中。如果你移动它,那么你必须做一些微小的改变。

更新

我没有按照您的说明理解您的意思。我是否也需要让 GetPatronById 成为一个任务函数——就像 Yuval 在下面所做的那样?

我的意思是这样的:

// The name of the class may be not the most suitable in this case.
public class Repo
{
    public static async Task<T> GetAsync<T>(string uri)
    {
        var client = GetHttpClient(uri);
        var content = await client.GetStringAsync(uri);
        var serializer = new JavaScriptSerializer();
        var t = serializer.Deserialize<T>(content);
        return t;
    }
}

public Patron GetPatronById(string barcode)
{
     string uri = "patrons/find?barcode=" + barcode;
     var Patron =  Repo.GetAsync<Patron>(uri).Result;
     return Patron;
}
于 2016-08-30T19:32:59.290 回答
2

泛型可以通过以下方式轻松完成:

private async Task<T> GetAsync(string uri)
{
    var client = GetHttpClient(uri);
    var content = await client.GetStringAsync(uri);
    return JsonConvert.DeserializeObject<T>(content);
}

注意事项:

  1. JavaScriptSerializer 已被弃用多年,请避免使用它。改为尝试Json.NET 。

  2. 这个:

    Patron Patron =  GetAsync(uri).Result;
    

    很危险并且可能导致潜在的死锁,尤其是在 Web API 中。您需要“一路异步”:

    public Task<Patron> GetPatronByIdAsync(string barcode)
    {
       string uri = $"patrons/find?barcode={barcode}";
       return GetAsync<Patron>(uri);
    }
    

并且只有您最顶层的调用者需要await. Task可能是一些控制器动作:

public async Task SomeAction()
{
     await GetPatronByIdAsync("hello");
}
于 2016-08-30T19:34:31.723 回答