[英]Working with WCF and task-based operations
我試圖使客戶端可以同時進行多次搜索,而不會影響搜索頁面的響應時間。 為此,我希望在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,所以沒有用。 還是我誤解了什么? 我應該在靜態方法中使用結果嗎?
我很遺憾地錯過了一些基本的東西,但我希望有人可以把我拉向正確的方向。 我真的會做到這一點!
正如本問答中所討論的, “.NET 4.5方式”是使您的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;
}
更多資源:
在ASP.NET 4.5中使用異步方法的魔力加上 Scott Hanselman撰寫的重要問題 - 博客文章
你可以這樣做:
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;
您需要將三個結果result1,result2和result3添加到任務數組中。
然后你可以這樣做:
Task.WaitAll(任務);
其中任務是數組。
http://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx
WaitAll完成后,您可以從每個任務中檢索SearchItem列表。
您的GetAsyncSearchItems
方法應如下所示(遵循基於任務的異步模式 ):
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
在這種情況下有效,但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
介紹很有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.