Task.WhenAny Может ли это быть решено из синхронного конвейера? - PullRequest
0 голосов
/ 28 ноября 2018

Я рассмотрел Как вызвать асинхронный метод из синхронного метода в C #? , чтобы получить разрешение асинхронного вызова в неасинхронной функции.

Я могу выполнить отдельные асинхронные задачи, используя решение A этой статьи.Но я не вижу, как это можно сделать, когда одна асинхронная функция сама содержит вызов массива асинхронных вызовов.Прямо сейчас он просто зависает при вызове

var result = task.WaitAndUnwrapException();

Вот что у меня есть

public static async Task<List<SearchModel>> GoAsync(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
        {    
            var taskList = new List<Task<List<SearchModel>>>
            {                    
                SearchRoutine1Async(search, cancellationToken),
                SearchRoutine2Async(search, cancellationToken)
            };

            Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList);

            return completedTask.Result;
        }

Пример задачи:

public static async Task<List<SearchModel>> SearchRoutine1Async(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
        {
            using (DBContext db = new DBContext)
            {
                var searchModels= await db.SearchModel
                    .Where(sm => sm.subKey1 = search.subKey1)
                    .ToListAsync(cancellationToken)
                    .ConfigureAwait(false)
                    ; 

                return searchModels;
            }
        }

Вызов из синхронной подпрограммы выглядит следующим образом, и он замирает в задаче. WaitAndUnwrapException ...:

var task = GoAsync(search);
var result = task.WaitAndUnwrapException();

Подводя итог ... если я обошел подпрограмму GoAsync и вызвал задачи по отдельности.. это работает, делая это из синхронной процедуры:

var task = SearchRoutine1Async(search);
var result = task.WaitAndUnwrapException();

1 Ответ

0 голосов
/ 28 ноября 2018

Видимо мне не хватало .ConfigureAwait (false) после

Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList);

на это:

Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList).ConfigureAwait(false);

@ KevinGrosse спасибо!

Не знаю, зачем мне это нужноэто хоть.Не требуется при работе в асинхронном конвейере.

...