使用WCF和基于任务的操作

时间:2013-11-27 15:18:16

标签: c# asp.net .net wcf asynchronous

我试图使客户端可以同时进行多次搜索,而不会影响搜索页面的响应时间。为此,我希望在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,所以它没有用。 还是我误解了什么?我应该在静态方法中使用结果吗?

我在这里错过了一些基本的东西,但我希望有人可以把我拉向正确的方向。我真的会做到这一点!

4 个答案:

答案 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;
}

更多资源:

答案 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有帮助。