асинхронная обработка в c # - PullRequest
       5

асинхронная обработка в c #

0 голосов
/ 26 сентября 2018

У меня есть сервис, который реализует функциональность для возврата данных из API анализа настроений.Клиент может запросить результаты от одного или всех механизмов, и я хочу сопоставить все данные вместе.Я хочу обработать эти асинхронные и дождаться их завершения, прежде чем возвращать набор результатов.Я новичок в асинхронном программировании, и я действительно не могу понять, как организовать код и как реализовать его синтаксически.Вот пример того, чего я пытаюсь достичь (я знаю, что это не работает, но вы поняли; надеюсь :-)):

    private ISentimentResponse ProcessRequest(ISentimentRequest request, SentimentEngineServices selectedEngines)
    {
        SentimentResponse response = new SentimentResponse();
        List<Task> taskList = new List<Task>();
        foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
        {
            if (((int)engineService & (int)selectedEngines) > 0)
            {
                ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
                Task<ISentimentEngineResult> task = new Task<ISentimentEngineResult>(engine.AnalyseSentimentASync(request));
                taskList.Add(task);
            }
        }
        if (taskList.Count > 0)
        {
            ISentimentEngineResult[] results = Task<ISentimentEngineResult>.WaitAll(taskList);
            foreach (result in results)
                response.Add(results);
        }
        return response;
    }

Движок имеет следующую реализацию кода движка.AnalyseSentimentASync:

    public ISentimentEngineResult AnalyseSentiment(ISentimentRequest request)
    {
        try
        {
            MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
            SentimentBatchResult sentiment = _client.Sentiment(sentimentList);
            KeyPhraseBatchResult keyPhrases = _client.KeyPhrases(sentimentList);
            return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
        }
        catch (Exception ex)
        {
            _logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
            throw;
        }
    }
    public async Task<ISentimentEngineResult> AnalyseSentimentAsync(ISentimentRequest request)
    {
        return AnalyseSentiment(request);
    }

Что мне нужно сделать и есть ли лучший способ добиться этого?

Я искал пример везде, но не могу найти тот, который касается моеготребования реализации, или весь подход совершенно не так!

Спасибо всем,

Stu.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Хорошо, вот оно:

        public ISentimentResponse AnalyseSentiment(ISentimentRequest request, SentimentEngineServices selectedEngines)
        {
            if (selectedEngines == SentimentEngineServices.None) throw new ArgumentException(nameof(selectedEngines));
            ValidateRequest(request);
            return ProcessRequestAsync(request, selectedEngines).Result;
        }
        private async Task<ISentimentResponse> ProcessRequestAsync(ISentimentRequest request, SentimentEngineServices selectedEngines)
        {
            SentimentResponse response = new SentimentResponse();
            List<Task<ISentimentEngineResult>> taskList = new List<Task<ISentimentEngineResult>>();
            foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
            {
                if (((int)engineService & (int)selectedEngines) > 0)
                {
                    ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
                    Task<ISentimentEngineResult> task = engine.AnalyseSentimentASync(request);
                    taskList.Add(task);
                }
            }
            if (taskList.Count > 0)
            {
                ISentimentEngineResult[] results = await Task.WhenAll(taskList);
                foreach (var result in results)
                    response.Add(result);
            }
            return response;
        }

И реализация интерфейса настроений:

 public async Task<ISentimentEngineResult> AnalyseSentiment(ISentimentRequest request)
        {
            try
            {
                MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
                SentimentBatchResult sentiment = await _client.SentimentAsync(sentimentList);
                KeyPhraseBatchResult keyPhrases = await _client.KeyPhrasesAsync(sentimentList);
                return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
            }
            catch (Exception ex)
            {
                _logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
                throw;
            }
        }

Спасибо FCin.

0 голосов
/ 26 сентября 2018

Вот как вы можете преобразовать его в асинхронный:

public async Task<ISentimentEngineResult> AnalyseSentimentAsync(ISentimentRequest request)
{
    try
    {
        MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
        SentimentBatchResult sentiment = await _client.SentimentAsync(sentimentList);
        KeyPhraseBatchResult keyPhrases = await _client.KeyPhrasesAsync(sentimentList);
        return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
    }
    catch (Exception ex)
    {
        _logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
        throw;
    }
}

private async Task<ISentimentResponse> ProcessRequestAsync(ISentimentRequest request, SentimentEngineServices selectedEngines)
{
    SentimentResponse response = new SentimentResponse();
    List<Task<ISentimentEngineResult>> taskList = new List<Task<ISentimentEngineResult>>();
    foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
    {
        if (((int)engineService & (int)selectedEngines) > 0)
        {
            ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
            Task<ISentimentEngineResult> task = engine.AnalyseSentimentASync(request);
            taskList.Add(task);
        }
    }
    if (taskList.Count > 0)
    {
        ISentimentEngineResult[] results = await Task.WhenAll(taskList);
        foreach (result in results)
            response.Add(results);
    }
    return response;
}

Помните, что вы должны вызывать его из какого-то обработчика событий.Я не знаю, какой фреймворк вы используете (wpf, asp.net, windows service, webapi).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...