是否可以等待任务集合的有效回报?

时间:2019-03-18 14:42:08

标签: c# multithreading task

我正在寻找使用Tasks数组来使用多种方法找到问题的解决方案。我的想法是,每种方法都使用不同的Task。有没有办法做Tasks.WaitFirst(task => task.Result == true)?到目前为止,我发现的所有解决方案都非常混乱,我正在考虑废除该想法,但想检查一下我是否没有丢失任何东西!

谢谢!

2 个答案:

答案 0 :(得分:2)

您应该使用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)获得第一个要完成的值。干净简单很不错。

如果您发布如何创建任务,那么我可以发布完整的答案。

答案 1 :(得分:0)

我认为这不是.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);
    }
}