如何要等到所有任务运行code之前完成 [英] How to wait until all tasks are finished before running code

查看:114
本文介绍了如何要等到所有任务运行code之前完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个多线程搜索,然后显示所有的结果,一旦任务完成运行,但目前我不知道如何处理结果一旦所有的任务都完成

我的code是如下:

 专用异步无效DoSearchAsync()
    {
        VAR productResults =等待SearchProductsAsync(CoreCache.AllProducts);
        VAR brochureResults =等待SearchBrochuresAsync(CoreCache.AllBrochures);        _searchResults.AddRange(productResults);
        _searchResults.AddRange(brochureResults);        ResultsCount = _searchResults.Count;
    }

其中, _searchResults 列表与LT;信息搜索结果>

我的理解是,它会同时执行两个等待着,然后将产品添加到搜索结果中。然而,当我把这个在我的控制器:

 公众的ActionResult指数(字符串SEARCHTEXT)
    {
        SearchHelper帮手=新SearchHelper(SEARCHTEXT);
        helper.DoSearchAsync();        返回查看(辅助);
    }

在搜索完成所以没有结果显示出来前,它显示页面。我如何让它等待结果显示页面之前完成?

我已经进去一看 Tasks.Wait ,但不知道如何将它应用到上面,预计任务的数组

 私人任务<名单,LT;信息搜索结果>> SearchProductsAsync(IEnumerable的<产品与GT;产品)
    {
        返回任务<名单,LT;信息搜索结果>> .Factory.StartNew(()=>的GetProducts(产品));
    }    私人任务<名单,LT;信息搜索结果>> SearchBrochuresAsync(IEnumerable的<资产和GT;小册子)
    {
        返回任务<名单,LT;信息搜索结果>> .Factory.StartNew(()=> GetBrochures(小册子));
    }


解决方案

每次调用 Factory.StartNew 时间或 Task.Run 一个ASP.NET控制器内,你抢从线程池。该线程可能会以其他方式提供一个到来的HTTP请求。所以,your're真的伤害你的web应用程序的可扩展性。这可能是一个严重的问题,这取决于HTTP多少并发请求的web应用程序有望获得。

您确定与?如果是这样,code可能是这样的:

 专用异步任务DoSearchAsync()
{
    VAR productResults = SearchProductsAsync(CoreCache.AllProducts);
    VAR brochureResults = SearchBrochuresAsync(CoreCache.AllBrochures);    等待Task.WhenAll(productResults,brochureResults);    _searchResults.AddRange(productResults.Result);
    _searchResults.AddRange(brochureResultsbrochure.Results);    ResultsCount = _searchResults.Count;
}公共异步任务<&的ActionResult GT;指数(字符串SEARCHTEXT)
{
    SearchHelper帮手=新SearchHelper(SEARCHTEXT);    等待helper.DoSearchAsync();    返回查看(辅助);
}

请注意,我改变异步无效异步任务 DoSearchAsync ,并提出您的控制器方法异步,所以它返回任务<的ActionResult方式>

I am trying to write a multi threading search and then display all the results once the tasks have finished running but currently I don't understand how to process the results once all the tasks are complete

My code is as follows:

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

Where _searchResults is a List<SearchResult>

My understanding is that it will do both of the awaits simultaneously and then add the products to the search results. However when I call this in my controller:

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

        return View(helper);
    }

It is displaying the page before the searches are complete so no results are showing up. How do I make it wait for the results to finish before showing the page?

I've had a look into Tasks.Wait but don't know how to apply it to the above as it expects an array of tasks

    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));
    }

解决方案

Every time you call Factory.StartNew or Task.Run inside an ASP.NET controller, you grab a thread from ThreadPool. That thread could be otherwise serving another incoming HTTP request. So, your're really hurting your web app scalability. This may be a serious issue, depending on how many concurrent HTTP requests your web app is expected to receive.

Are you OK with that? If so, the code could look like this:

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);
}

Note I changed async void to async Task for DoSearchAsync, and made your controller method async, so it returns Task<ActionResult>.

这篇关于如何要等到所有任务运行code之前完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆