如何在运行代码之前等待所有任务完成

Pet*_*ete 4 asp.net-mvc multithreading async-await c#-5.0

我正在尝试编写多线程搜索,然后在任务完成运行后显示所有结果但目前我不明白如果所有任务完成后如何处理结果

我的代码如下:

    private async void DoSearchAsync()
    {
        var productResults = await SearchProductsAsync(CoreCache.AllProducts);
        var brochureResults = await SearchBrochuresAsync(CoreCache.AllBrochures);

        _searchResults.AddRange(productResults); 
        _searchResults.AddRange(brochureResults);

        ResultsCount = _searchResults.Count;
    }
Run Code Online (Sandbox Code Playgroud)

哪里_searchResultsList<SearchResult>

我的理解是,它将同时执行两个等待,然后将产品添加到搜索结果中.但是,当我在我的控制器中调用它时:

    public ActionResult Index(string searchText)
    {
        SearchHelper helper = new SearchHelper(searchText);
        helper.DoSearchAsync();

        return View(helper);
    }
Run Code Online (Sandbox Code Playgroud)

它在搜索完成之前显示页面,因此没有显示任何结果.如何在显示页面之前等待结果完成?

我已经看了一下,Tasks.Wait但不知道如何将它应用到上面,因为它需要一系列任务

    private Task<List<SearchResult>> SearchProductsAsync(IEnumerable<Product> products)
    {
        return Task<List<SearchResult>>.Factory.StartNew(() => GetProducts(products));
    }

    private Task<List<SearchResult>> SearchBrochuresAsync(IEnumerable<Assets> brochures)
    {
        return Task<List<SearchResult>>.Factory.StartNew(() => GetBrochures(brochures));
    }
Run Code Online (Sandbox Code Playgroud)

nos*_*tio 13

每次调用Factory.StartNewTask.Run在ASP.NET控制器内部时,都会从中获取一个线程ThreadPool.该线程可以以其他方式提供另一个传入的HTTP请求.所以,你真的在​​损害你的网络应用程序可扩展性.这可能是一个严重的问题,具体取决于您的Web应用程序预计会收到多少并发HTTP请求.

那样你觉得可以吗?如果是这样,代码可能如下所示:

private async Task DoSearchAsync()
{
    var productResults = SearchProductsAsync(CoreCache.AllProducts);
    var brochureResults = SearchBrochuresAsync(CoreCache.AllBrochures);

    await Task.WhenAll(productResults, brochureResults);

    _searchResults.AddRange(productResults.Result); 
    _searchResults.AddRange(brochureResultsbrochure.Results);

    ResultsCount = _searchResults.Count;
}

public async Task<ActionResult> Index(string searchText)
{
    SearchHelper helper = new SearchHelper(searchText);

    await helper.DoSearchAsync();

    return View(helper);
}
Run Code Online (Sandbox Code Playgroud)

注意我改async voidasync TaskDoSearchAsync,并提出您的控制器的方法async,所以它返回Task<ActionResult>.

  • @Pete你应该改变你接受的答案,IMO.Noseratio是正确和可取的,Eduardo不是.将接受的答案改为更好的答案是不是正确的,即使它是后来的?特别是因为粗略阅读Eduardo将会导致一个非常糟糕的模式 - 使用异步调用启动I/O绑定工作的新线程是不好的做法,特别是现在替代方案同样容易. (3认同)
  • @Pete,这不是`await Task.WhenAll`和`Task.WaitAll`之间的区别.如果您希望将其置于注释格式中,则差异是异步延续与同步阻塞. (2认同)