Можно ли ожидать верного возврата из Коллекции задач? - PullRequest
0 голосов
/ 18 марта 2019

Я хочу использовать массив Tasks, чтобы найти решение проблемы, используя несколько методов.Идея в том, что я использую разные Task для каждого метода.Есть ли способ сделать Tasks.WaitFirst(task => task.Result == true)?Любые решения, которые я нашел до сих пор, были очень грязными, я думаю отказаться от идеи, но хочу проверить, что я ничего не пропускаю!

Спасибо!

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Вы должны использовать Microsoft Reactive Framework (он же Rx) - NuGet System.Reactive и добавить using System.Reactive.Linq; - тогда вы можете сделать это:

void Main()
{
    var query =
        from n in Observable.Range(0, 25)
        from v in Observable.FromAsync(() => GetValueAsync())
        select v;

    query.Take(1).Subscribe(x => Console.WriteLine(x));
}

private Random _random = new Random();

public async Task<int> GetValueAsync()
{
    var value = _random.Next(5, 100);
    Console.WriteLine($"!{value}");
    await Task.Delay(TimeSpan.FromSeconds(value));
    return value;
}

В итоге вы получите простой запрос, который вы можете использовать .Take(1), чтобы завершить первое значение. Это приятно, чисто и просто.

Если вы опубликуете, как вы создаете задачи, я могу опубликовать полный ответ.

0 голосов
/ 18 марта 2019

Я не думаю, что это что-то, что есть в .net, но вы можете написать свою собственную версию.Что-то вроде этого

public static async Task<T> WhenFirst<T>(IEnumerable<Task<T>> tasks, Func<T, bool> predicate)
{
    var taskArray = tasks.ToArray();
    var completedTask = await Task.WhenAny(taskArray);

    if (predicate(await completedTask))
    {
        return await completedTask;
    }
    else
    {
        var notCompletedTasks = new List<Task<T>>();

        foreach(var task in taskArray)
        {
            if (task.IsCompleted && predicate(await task)) return await task;
            else notCompletedTasks.Add(task);
        }

        return await WhenFirst(notCompletedTasks, predicate);
    }
}
...