rud*_*ter 6 c# task async-await blockingcollection
我将后台任务添加到阻止集合(在后台添加).
我在GetConsumingEnumerable返回的Enumerable上等待Task.WhenAll.
我的问题是:Task.WhenAll的重载是否接收到IEnumerable"准备好"可能会收到无穷无尽的任务?
我只是不确定我是否可以这样做,或者它是否意味着以这种方式使用?
private async Task RunAsync(TimeSpan delay, CancellationToken cancellationToken)
{
using (BlockingCollection<Task> jobcollection = new BlockingCollection<Task>())
{
Task addingTask = Task.Run(async () =>
{
while (true)
{
DateTime utcNow = DateTime.UtcNow;
var jobs = Repository.GetAllJobs();
foreach (var job in GetRootJobsDue(jobs, utcNow))
{
jobcollection.Add(Task.Run(() => RunJob(job, jobs, cancellationToken, utcNow), cancellationToken), cancellationToken);
}
await Task.Delay(delay, cancellationToken);
}
}, cancellationToken);
await Task.WhenAll(jobcollection.GetConsumingEnumerable(cancellationToken));
}
}
Run Code Online (Sandbox Code Playgroud)
因为你的目标仅仅是等待,直到取消标记被取消,你应该做的是.出于其他人解释的原因,使用WhenAll无限的任务序列并不是解决这个问题的方法.有更简单的方法来完成永远不会完成的任务.
await new TaskCompletionSource<bool>().Task
.ContinueWith(t => { }, cancellationToken);
Run Code Online (Sandbox Code Playgroud)
Task.WhenAll无法处理无数个任务.它将首先(同步)等待枚举完成,然后(异步)等待它们全部完成.
如果要以异步方式对序列作出反应,则需要使用IObservable<Task>(Reactive Extensions).您可以将TPL数据流BufferBlock用作可以使用同步或异步代码的"队列",并且可以轻松转换为IObservable<Task>.
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |