Veg*_*gar 6 .net c# linq enumeration async-await
想象一下以下课程:
public class Checker
{
public async Task<bool> Check() { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,想象一下这个类的实例列表:
IEnumerable<Checker> checkers = ...
Run Code Online (Sandbox Code Playgroud)
现在我想控制每个实例都会返回true:
checkers.All(c => c.Check());
Run Code Online (Sandbox Code Playgroud)
现在,这不会编译,因为Check()返回Task<bool>不是a bool.
所以我的问题是:我怎样才能最好地列举检查器列表?如果检查器返回,我怎样才能快速进行枚举false?(我认为All( )已经存在的事情)
Ste*_*ary 10
"异步序列"总是会引起一些混乱.例如,目前尚不清楚您所需的语义是否为:
还有第三种可能性(同时启动所有检查,并按顺序评估它们),但在这种情况下这将是愚蠢的.
我建议将Rx用于异步序列.它为您提供了很多选择,而且有点难以学习,但它也会迫使您思考您想要的内容.
以下代码将同时启动所有检查并在完成时对其进行评估:
IObservable<bool> result = checkers.ToObservable()
.SelectMany(c => c.Check()).All(b => b);
Run Code Online (Sandbox Code Playgroud)
它首先将棋子序列转换为可观察者,然后调用Check它们,并检查它们是否全部true.第一个Check用false值完成将导致result产生一个false值.
相反,以下代码将一次启动一个检查,按顺序评估它们:
IObservable<bool> result = checkers.Select(c => c.Check().ToObservable())
.Concat().All(b => b);
Run Code Online (Sandbox Code Playgroud)
它首先将检查器序列转换为可观察序列,然后连接这些序列(一次启动一个序列).
如果你不想使用observables并且不想混淆订阅,你可以await直接使用它们.例如,呼叫Check所有检查员并在完成后评估结果:
bool all = await checkers.ToObservable().SelectMany(c => c.Check()).All(b => b);
Run Code Online (Sandbox Code Playgroud)
如果检查器返回false,我怎样才能快速枚举枚举?
这将按完成顺序检查任务的结果.因此,如果第一个任务#5完成,并返回false,则该方法立即返回false,而不管其他任务如何.永远不会检查较慢的任务(#1,#2等).
public static async Task<bool> AllAsync(this IEnumerable<Task<bool>> source)
{
var tasks = source.ToList();
while(tasks.Count != 0)
{
var finishedTask = await Task.WhenAny(tasks);
if(! finishedTask.Result)
return false;
tasks.Remove(finishedTask);
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
用法:
bool result = await checkers.Select(c => c.Check())
.AllAsync();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1019 次 |
| 最近记录: |