鉴于一定数量的请求对象(最多9个),我需要异步地调用Web服务端点相同的次数。对于public class TabViewPagerAdapter extends FragmentPagerAdapter {
private String[] title;
public TabViewPagerAdapter(FragmentManager manager, String[] titleArray) {
super(manager);
this.title = titleArray;
}
@Override
public Fragment getItem(int position) {
return TabFragment.getInstance(position);
}
@Override
public int getCount() {
return title.length;
}
@Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
,我们使用.NET 4.0
和delegate
实现了这一目标。
是否有更好的方法将IAsyncResult
,asyc/await
或将两者与TPL
结合使用?
按照此answer的建议,将.NET 4.6.1
与Parallel.ForEach
一起使用将是最佳选择吗?
同步代码示例:
ConcurrentBag
编辑/更新1 :基于@Thierry的回答,我创建了一个示例代码,假设请求和响应对象中都有一个public List<WbsResponse> GetWbsResults()
{
List<WbsRequest> requests = CompileWbsRequests();
List<WbsResponse> results = new List<WbsResponse>();
foreach (var request in requests)
{
//Call same web service endpoint n number of times
var response = CallWebService(request);
results.Add(response);
}
//do something with results
return results;
}
private WbsResponse CallWebService(WbsRequest request)
{
//Call web service
}
属性来标记请求/响应订购:
Order
编辑/更新2 :基于this线程,我对更新1进行了一些更改:
public List<WbsResponse> GetWbsResults()
{
List<WbsRequest> requests = CompileWbsRequests();
List<WbsResponse> results = new List<WbsResponse>();
Parallel.ForEach(requests, (request) => {
var response = CallWebService(request);
response.Order = request.Order;
results.Add(response);
});
results = results.OrderBy(r => r.Order).ToList();
//do something with results
return results;
}
private WbsResponse CallWebService(WbsRequest request)
{
//Call web service
}
需求摘要:
答案 0 :(得分:1)
因为每个任务的完成时间都不一样,所以我认为您应该对请求进行编号,并以此编号来排序响应。
在请求中,您初始化一个数字,并将此数字传递给相关联的响应。最后,当我得到结果时,我将其排序。 像这样:
public async Task<List<WbsResponse>> GetWbsResults()
{
List<WbsRequest> requests = CompileWbsRequests();
List<Task<WbsResponse>> tasks = new List<Task<WbsResponse>>();
for (var i = 0; i < requests.Count; i++)
{
var task = new Task<WbsResponse>(() => { CallWebService(WbsRequest); });
tasks.Add(task);
}
var responses = await Task.WhenAll(tasks);
var responsesOrdered = responses.OrderBy(r => r.Order)
//do something with results
return results;
}
public List<WbsRequest> CompileWbsRequests()
{
//create requests
foreach(var request in requests)
{
request.Order += 1;
}
}
private WbsResponse CallWebService(WbsRequest request)
{
//Call web service
reponse.order = request.order;
return reponse;
}
答案 1 :(得分:0)
我认为您可以使用Task.WaitAll
来使代码以异步方式工作,并且看起来也会更漂亮:
public List<WbsResponse> GetWbsResults()
{
List<WbsRequest> requests = CompileWbsRequests();
var responses = await Task.WhenAll(requests.Select(CallWebService));
return responses;
}
但是您必须按如下所示修改此方法以返回任务:
private async Task<WbsResponse> CallWebService(WbsRequest request)
{
//Call web service
}