Reputation: 369
I'm trying to make it possible for a client to make several searches at the same time without it affecting the response time of the seach page. To do this i was hoping to use .NET 4.5's task-based operations in WCF but I'm having troubles understanding the logic.
What I want my end result to be is to do multiple calls to the WCF API and then merge these into one big result and order it by each search items relevence.
This is how my code looks like today:
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;
}
}
Basicly, what I need to know is what to do with each result (result1, result2, result3) after i get them back. I though i was going to be able to call result1.Result after each method call but by then they aren't yet computed so it won't do any good.
While I was trying stuff before my GetAsyncSearchItems method looked something like this:
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);
}
When i did this i was able to retrieve the result in the list object but I wasn't able to return it to my Page_Load since async method can only return void, Task or Task so it was of no use. Or am I misunderstanding something? Should I work inside the static method with the result?
I'm probobly missing something basic here but I'm hoping someone can stear me in the right direction. I would really apreachiate it!
Upvotes: 0
Views: 1099
Reputation: 457197
Your GetAsyncSearchItems
method should look like this (following the 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;
}
Once you have that method, you can write Page_Load
as such:
protected async void Page_Load(object sender, EventArgs e)
{
_client = new SwepubSearchServiceClient();
var results = await GetSearchItemsAsync();
...
}
While async void
works in this scenario, the ASP.NET team prefers you use RegisterAsyncTask
, as such:
protected void Page_Load(object sender, EventArgs e)
{
_client = new SwepubSearchServiceClient();
RegisterAsyncTask(new PageAsyncTask(PageLoadAsync));
}
private async Task PageLoadAsync()
{
var results = await GetSearchItemsAsync();
...
}
You may find my async
intro helpful.
Upvotes: 0
Reputation: 16563
The ".NET 4.5 way" of doing it, as discussed in this Q&A, is to make your Page_Load
method async
. Then you can call your async
method, and ASP.NET will do the rest towards the client:
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;
}
More resources:
The Magic of using Asynchronous Methods in ASP.NET 4.5 plus an important gotcha - blog post by Scott Hanselman
Here's a video tutorial on Async in ASP.NET given in that answer I linked to.
Upvotes: 1
Reputation: 2476
You can do it like this:
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;
Upvotes: 1
Reputation: 14682
You need to add your three results, result1, result2 and result3 to an array of Tasks.
Then you can do this:
Task.WaitAll(tasks);
where tasks is the array.
http://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx
After the WaitAll completes, you can retrieve the lists of SearchItems from each task.
Upvotes: 0