创建通用异步任务函数
本文关键字:任务 函数 异步 创建 | 更新日期: 2023-09-27 18:05:02
我创建了一个函数,它返回一个使用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;
}
泛型方法呢?
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;
}
Generic可以很容易地完成:
private async Task<T> GetAsync(string uri)
{
var client = GetHttpClient(uri);
var content = await client.GetStringAsync(uri);
return JsonConvert.DeserializeObject<T>(content);
}
注意事项:
JavaScriptSerializer已经被弃用很长时间了,避免使用它。尝试使用Json。净。
:
Patron Patron = GetAsync(uri).Result;
是危险的,可能导致潜在的死锁,特别是在Web API中。你需要使用"async all the way":
public Task<Patron> GetPatronByIdAsync(string barcode) { string uri = $"patrons/find?barcode={barcode}"; return GetAsync<Patron>(uri); }
只有你的最高层调用者需要Task
上的await
。可能是一些控制器动作:
public async Task SomeAction()
{
await GetPatronByIdAsync("hello");
}