【问题标题】:Is it possible to await a valid return from a Collection of Tasks?是否可以等待任务集合的有效返回?
【发布时间】:2019-03-18 14:42:07
【问题描述】:

我正在寻找使用Tasks 的数组来使用多种方法找到问题的解决方案。我的想法是我为每种方法使用不同的Task。有没有办法做一个Tasks.WaitFirst(task => task.Result == true)?到目前为止,我发现的任何解决方案都非常混乱,我正在考虑放弃这个想法,但想检查一下我没有遗漏什么!

谢谢!

【问题讨论】:

  • 所以您基本上希望Task.WhenAny 带有谓词,对吗?请参阅this

标签: c# multithreading task


【解决方案1】:

您应该使用 Microsoft 的响应式框架(又名 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) 来获取要完成的第一个值。很干净很简单。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2019-07-22
      • 2011-07-01
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 2014-10-01
      相关资源
      最近更新 更多