我有一个我从另一个开发人员继承的Windows服务,它运行速度非常慢,并且对eBay API有很多慢速调用.我希望在没有太多重构的情况下加快速度.
我刚刚开始考虑使用c#async/await尝试使用这些慢速调用来运行异步.这就是我想要实现的目标:
我有一个非常繁忙的方法,可以进行如下调用:
getProducts
getCategories
getVehicles
getImages
Run Code Online (Sandbox Code Playgroud)
我的想法是我可以简单地将方法更改为async并添加Task<T>到返回类型,如下所示:
public async Task<String> ProcessAdditionalProductDetialsAsync(ItemType oItem)
{
String additionalProductDetails = string.Empty;
if (oItem.ItemSpecifics.Count > 0)
{
foreach (NameValueListType nvl in oItem.ItemSpecifics)
{
if (nvl.Value.Count > 0)
{
foreach (string s in nvl.Value)
{
additionalProductDetails += "<li><strong>" + nvl.Name + ":</strong> " + s + "</li>";
}
}
}
}
return additionalProductDetails;
}
Run Code Online (Sandbox Code Playgroud)
然后等待调用它们:
Task<String> additionalProductDetials = ebayPartNumbers.ProcessAdditionalProductDetialsAsync(item);
Task<PartNumberCollection> partNumberCollection = ebayPartNumbers.ProcessPartNumbersAsync(item);
await Task.WhenAll(partNumberCollection, additionalProductDetials);
Run Code Online (Sandbox Code Playgroud)
如何获取返回的类型以便我可以使用它们?我尝试过只使用partNumberCollection但它只有await可用的属性.
Ufu*_*arı 19
在Task类上使用Result属性:
await Task.WhenAll(partNumberCollection, additionalProductDetials);
var partNumberCollectionResult = partNumberCollection.Result;
var additionalProductDetialsResult = additionalProductDetials.Result;
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 14
如果返回的任务Task.WhenAll已完成,则表示您传递给它的所有任务也已完成.这反过来意味着您可以使用Result每个任务的属性,而不会有阻塞的风险.
string details = additionalProductDetials.Result;
Run Code Online (Sandbox Code Playgroud)
或者,您可以等待任务,以便与其他异步代码保持一致:
string details = await additionalProductDetials;
Run Code Online (Sandbox Code Playgroud)
同样,这保证不会阻止 - 如果您之后Task.WhenAll由于某种原因删除了(例如,您很高兴在获得部件号收集之前使用详细信息启动另一项任务),那么您不需要改变代码.
您的async方法缺乏await运算符并将同步运行.当您调用非阻塞API时,您可以使用Task.Run()在后台线程上执行cpu绑定的工作.
public async Task<String> ProcessAdditionalProductDetialsAsync(ItemType oItem)
{
return await Task.Run(() =>
{
String additionalProductDetails = string.Empty;
if (oItem.ItemSpecifics.Count > 0)
{
foreach (NameValueListType nvl in oItem.ItemSpecifics)
{
if (nvl.Value.Count > 0)
{
foreach (string s in nvl.Value)
{
additionalProductDetails += "<li><strong>" + nvl.Name + ":</strong> " + s + "</li>";
}
}
}
}
return additionalProductDetails;
});
}
Run Code Online (Sandbox Code Playgroud)
并得到结果
var detail = await ProcessAdditionalProductDetialsAsync(itemType);
var result = ProcessAdditionalProductDetialsAsync(itemType).Result;
Run Code Online (Sandbox Code Playgroud)