我试图使客户端可以同时进行多次搜索,而不会影响搜索页面的响应时间。为此,我希望在WCF中使用.NET 4.5的基于任务的操作,但是我在理解逻辑时遇到了麻烦。
我希望我的最终结果是对WCF API进行多次调用,然后将这些调用合并为一个大结果,并按每个搜索项目的顺序排序。
这就是我今天的代码:
public partial class WebForm1 : System.Web.UI.Page
{
private static SwepubSearchServiceClient _client;
private static List<SearchItem> _searchItems = new List<SearchItem>();
protected void Page_Load(object sender, EventArgs e)
{
_client = new SwepubSearchServiceClient();
var result1 = GetAsyncSearchItems("query1", "subQuery1");
var result2 = GetAsyncSearchItems("query2", "subQuery2");
var result3 = GetAsyncSearchItems("query3", "subQuery3");
// What to do here?
}
private static async Task<SearchItem[]> GetAsyncSearchItems(string query = "", string subQuery = "")
{
var task = _client.DoSearchSimpleAsync(query, subQuery);
return await task;
}
}
基本上,我需要知道的是在我找回它们之后如何处理每个结果(result1,result2,result3)。我虽然我能够在每次方法调用之后调用result1.Result,但到那时它们还没有计算好,所以它不会有任何好处。
在我的GetAsyncSearchItems方法看起来像这样之前我正在尝试的东西:
private static async void GetAsyncSearchItems()
{
var task1 = _client.DoSearchSimpleAsync("query1", "subQuery1");
var task2 = _client.DoSearchSimpleAsync("query2", "subQuery2");
var task3 = _client.DoSearchSimpleAsync("query3", "subQuery3");
var result1 = await task1;
var date1 = DateTime.Now.TimeOfDay;
var result2 = await task2;
var date2 = DateTime.Now.TimeOfDay;
var result3 = await task3;
var date3 = DateTime.Now.TimeOfDay;
var list = new List<SearchItem>();
list.AddRange(result1);
list.AddRange(result2);
list.AddRange(result3);
}
当我这样做时,我能够在列表对象中检索结果但我无法将其返回到我的Page_Load,因为异步方法只能返回void,Task或Task,所以它没有用。 还是我误解了什么?我应该在静态方法中使用结果吗?
我在这里错过了一些基本的东西,但我希望有人可以把我拉向正确的方向。我真的会做到这一点!
答案 0 :(得分:1)
执行此操作的“.NET 4.5方式”as discussed in this Q&A,就是制作Page_Load
方法async
。然后,您可以调用async
方法,ASP.NET将对客户端执行其余操作:
protected async void Page_Load(object sender, EventArgs e)
{
...
var results = await GetAsyncSearchItems(...)
... do something with the results
}
private static async SearchItem[] GetAsyncSearchItems()
{
... await stuff
return list;
}
更多资源:
The Magic of using Asynchronous Methods in ASP.NET 4.5 plus an important gotcha - Scott Hanselman撰写的博文
这是我链接到的答案中给出的video tutorial on Async in ASP.NET。
答案 1 :(得分:1)
你可以这样做:
var task1 = _client.DoSearchSimpleAsync("query1", "subQuery1");
var task2 = _client.DoSearchSimpleAsync("query2", "subQuery2");
var task3 = _client.DoSearchSimpleAsync("query3", "subQuery3");
await Task.WhenAll(task1, task2, task3);
var result1 = task1.Result;
var date1 = DateTime.Now.TimeOfDay;
var result2 = task2.Result;
var date2 = DateTime.Now.TimeOfDay;
var result3 = task3.Result;
var date3 = DateTime.Now.TimeOfDay;
答案 2 :(得分:0)
您需要将三个结果result1,result2和result3添加到任务数组中。
然后你可以这样做:
Task.WaitAll(任务);
其中tasks是数组。
http://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx
WaitAll完成后,您可以从每个任务中检索SearchItem列表。
答案 3 :(得分:0)
您的GetAsyncSearchItems
方法应该如下所示(Task-based Asynchronous Pattern之后):
private static async Task<List<SearchItem>> GetSearchItemsAsync()
{
var task1 = _client.DoSearchSimpleAsync("query1", "subQuery1");
var task2 = _client.DoSearchSimpleAsync("query2", "subQuery2");
var task3 = _client.DoSearchSimpleAsync("query3", "subQuery3");
var results = await Task.WhenAll(task1, task2, task3);
var list = new List<SearchItem>();
list.AddRange(results[0]);
list.AddRange(results[1]);
list.AddRange(results[2]);
return list;
}
一旦你有了这个方法,就可以这样写Page_Load
:
protected async void Page_Load(object sender, EventArgs e)
{
_client = new SwepubSearchServiceClient();
var results = await GetSearchItemsAsync();
...
}
虽然async void
适用于此方案,但您使用prefers的ASP.NET小组RegisterAsyncTask
仍然如此:
protected void Page_Load(object sender, EventArgs e)
{
_client = new SwepubSearchServiceClient();
RegisterAsyncTask(new PageAsyncTask(PageLoadAsync));
}
private async Task PageLoadAsync()
{
var results = await GetSearchItemsAsync();
...
}
您可能会发现我的async
intro有帮助。