locked
Как сделать несколько потоков в async методе. RRS feed

  • Вопрос

  • Добрый день, подскажите пожалуйста что я делаю не так?

    В общем есть метод:

             public async void StartAsyncSearchLinkParsing(RewriteMode CurrentRewriteMode)
                {
                    bool HasErrors = false;
    
                    cts = new CancellationTokenSource();
    
                    var progressIndicator = new Progress<int>(ReportProgress);
    
    
                    try
                    {
                        var PPSettings = ReturnMainAdminForm().AppSettings.ParsingEntries.GetEnabledParsingEntries();
    
                        CurrentImportData = await GetSearchUrl(CurrentImportData, PPSettings, CurrentRewriteMode, progressIndicator, cts.Token);
    
                    }
                    catch (OperationCanceledException ex)
                    {
                        ReportProgress(0);
                        CurrentImportData.TableList.Clear();
                        HasErrors = true;
                    }
    
                    finally
                    {
                        ReportProgress(0);
                        dataGridView1.DataSource = CurrentImportData.TableList;
                    }
    
    
                }

    Он выполняет главное действие GetSearchUrl и заодно отслеживает завершенность процесса в процентах при помощи progressIndicator.

    Метод GetSearchUrl выглядит вот так:

                public async Task<ImportAquaDataTable> GetSearchUrl(ImportAquaDataTable CurrentImports,
                                                                ParsingSettingsList ParsingSettings,
                                                                RewriteMode RewriteMode,
                                                                IProgress<int> progress, CancellationToken ct)
                {
                    // Разворачиваем ассинхронный метод
                    ImportAquaDataTable MyAsyncProc = await Task<ImportAquaDataTable>.Run(() =>
                    {
                        //ImportAquaDataTable Result = new ImportAquaDataTable();
                        AdvancedParser Parser = new AdvancedParser();
    
                        int IndexOfProduct = 0;
                        int Maximum = CurrentImports.TableList.Count - 1;
    
    
                        List<string> LinksResults = new List<string>();
    
                        for (int i = 0; i < CurrentImports.TableList.Count; i++)
                        {
                            bool CanParse = CanParseUrlLink(CurrentImports.TableList[i].UrlLink, RewriteMode);
    
                            if (CanParse == true)
                            {
    
                                LinksResults.Clear();
    
                                string TextToFind = CurrentImports.TableList[i].Articul;
    
                                string UrlResult = "";
    
    
    
                                foreach (var ParsingEntry in ParsingSettings)
                                {
                                    if (ParsingEntry != null)
                                    {
                                        string StopWordsTextToFind = ParsingEntry.StopWordsList.ApplyStopWords(TextToFind);
                                        try
                                        {
                                            UrlResult = Parser.ParseResultUrlLink(TextToFind, ParsingEntry);
    
                                        }
                                        catch
                                        {
    
                                        }
                                        finally
                                        {
    
                                        }
                                    }
    
                                    if (String.IsNullOrEmpty(UrlResult) == false)
                                    {
                                        LinksResults.Add(UrlResult);
                                    }
                                }
    
                                CurrentImports.TableList[i].UrlLink = LinksResults.FirstOrDefault();
    
                            }
    
                            // Рутина
                            int CurrentPercentage = Base.GetPercentage(Maximum, IndexOfProduct);
    
                            ct.ThrowIfCancellationRequested();
    
                            if (progress != null)
                            {
                                progress.Report(CurrentPercentage);
                            }
    
                            IndexOfProduct++;
                        }
    
    
                        return CurrentImports;
    
                    }, ct);
    
                    return MyAsyncProc;
                }
     

    Тут главный метод - это обычный метод класса Parser.ParseResultUrlLink, я решил создать асинхронный вариант этого метода, чтобы запускать поток параллельно после каждой итерации цикла foreach (var ParsingEntry in ParsingSettings).

            public async Task<string> ParseResultUrlLinkAsync(string TextToSearch,
                                                         ParsingSettingsEntry CurrentPP,
                                                         CancellationToken ct)
            {
                // Разворачиваем ассинхронный метод
                string MyAsyncProc = await Task<string>.Run(() =>
                {
    
    
                    string res = "";
                    string SearchUrl = MakeSearchUrl(TextToSearch, CurrentPP);
                    HtmlDocument doc = GetPAge_HTML_Doc(SearchUrl);
    
                    if (CurrentPP != null)
                    {
                        AdvancedParserScripterClass Scripter = new AdvancedParserScripterClass();
    
                        List<string> ResultUrlLink = new List<string>() { };
                        ResultUrlLink = this.Parse(SearchUrl, CurrentPP.ResultSearchLink_Command, CurrentPP.ResultSearchLink__WordProcessing);
                        res = ResultUrlLink.FirstOrDefault();
                    }
                    if (String.IsNullOrEmpty(res) == false)
                    {
                        res = WebUnion(CurrentPP.SettingName, res);
                        //res = CurrentPP.SettingName + res;
                    }
    
                    ct.ThrowIfCancellationRequested();
    
                    return res;
    
    
                }, ct);
    
                return MyAsyncProc;
            }

    Меняю обычный метод на асинк в GetSearchUrl , всего одна строчка

    UrlResult = await Parser.ParseResultUrlLinkAsync(TextToFind, ParsingEntry, cts.Token);

    Строка выделяется красным, в хинте - Оператор await можно использовать только в лямбда-выражениях с модификатором async. Что я сделал не так, в чем ошибка? Я хочу чтобы каждый запуск метода  ParseResultUrlLinkAsync выполнялся быстро в отдельном потоке, все результаты стекали к файнэли, например. Ну а дальше я бы уже делал с этими данными все что требуется по задаче. Подскажите пожалуйста, как это сделать наиболее верным способом в данном случае?


    7 августа 2014 г. 23:58

Ответы

  • Лямбда в методе GetSearchUrl не объявлена как асинхронная. Поставьте слово async перед пустыми круглыми скобками, ошибка должна исчезнуть.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Предложено в качестве ответа Taras KovalenkoBanned 8 августа 2014 г. 11:18
    • Помечено в качестве ответа Kutcher 9 августа 2014 г. 20:34
    8 августа 2014 г. 9:26

Все ответы

  • Лямбда в методе GetSearchUrl не объявлена как асинхронная. Поставьте слово async перед пустыми круглыми скобками, ошибка должна исчезнуть.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Предложено в качестве ответа Taras KovalenkoBanned 8 августа 2014 г. 11:18
    • Помечено в качестве ответа Kutcher 9 августа 2014 г. 20:34
    8 августа 2014 г. 9:26
  • Спасибо, все заработало как надо!
    9 августа 2014 г. 20:35