C#数据流:等待ConcurrentExclusiveSchedulerPair启动的所有任务完成

C#数据流:等待ConcurrentExclusiveSchedulerPair启动的所有任务完成,c#,asynchronous,task-parallel-library,tpl-dataflow,C#,Asynchronous,Task Parallel Library,Tpl Dataflow,我有一个要执行的操作列表,可以在用户交互时取消。非常简单,但是,ConcurrentExclusiveSchedulerPair.Completion永远不会结束。下面是一个例子: static void Main(string[] args) { var taskSchedulerPair = new ConcurrentExclusiveSchedulerPair(); var cts = new CancellationTokenSource(); var opti

我有一个要执行的操作列表,可以在用户交互时取消。非常简单,但是,
ConcurrentExclusiveSchedulerPair.Completion
永远不会结束。下面是一个例子:

static void Main(string[] args)
{
    var taskSchedulerPair = new ConcurrentExclusiveSchedulerPair();
    var cts = new CancellationTokenSource();
    var optiions = new ExecutionDataflowBlockOptions
    {
        TaskScheduler = taskSchedulerPair.ConcurrentScheduler,
        CancellationToken = cts.Token,
        MaxDegreeOfParallelism = 5
    };
    var a1 = new ActionBlock<int>(new Func<int, Task<int>>(Moo), optiions);
    for (var i = 0; i < 20; i++) a1.Post(i);
    Console.WriteLine("Press any key to cancel...");
    Console.ReadKey(false);
    Console.WriteLine("Cancelling...");
    cts.Cancel();
    // taskSchedulerPair.Complete();
    taskSchedulerPair.Completion.Wait();
    // This never prints
    Console.WriteLine("Done.");
    Console.ReadKey(false);
}

public static async Task<int> Moo(int ms)
{
    Console.WriteLine("Starting: " + ms);
    await Task.Delay(4000);
    Console.WriteLine("Ending" + ms);
    return ms + 100;
}
static void Main(字符串[]args)
{
var taskSchedulerPair=新的ConcurrentExclusiveSchedulerPair();
var cts=新的CancellationTokenSource();
var options=新的ExecutionDataflowBlockOptions
{
TaskScheduler=taskSchedulerPair.ConcurrentScheduler,
CancellationToken=cts.Token,
MaxDegreeOfParallelism=5
};
var a1=新操作块(新功能(Moo)、选项);
对于(var i=0;i<20;i++)a1.Post(i);
Console.WriteLine(“按任意键取消…”);
Console.ReadKey(false);
Console.WriteLine(“取消…”);
cts.Cancel();
//taskSchedulerPair.Complete();
taskSchedulerPair.Completion.Wait();
//这张照片从不打印
控制台。WriteLine(“完成”);
Console.ReadKey(false);
}
公共静态异步任务Moo(int-ms)
{
控制台写入线(“开始:+ms”);
等待任务。延迟(4000);
控制台写入线(“结束”+ms);
返回ms+100;
}
来自

调用Complete是可选的仅当您依赖Completion属性来通知所有处理已完成时,才有必要执行此操作


因此,如果要在
Completion
属性上
等待
,则必须调用调度程序上的
Complete()
。此行为与数据流块相同;要依赖
Completion
属性,必须在块上调用
Complete()

为什么要使用ConcurrentExclusiveSchedulerPair?无论如何,需要完成的是动作块,而不是调度程序。对于正常终止,您应该调用
a1.Complete()然后<代码>等待a1.完成。如果您遵循,这只是出于说明目的,是一个有点不幸的选择。不需要使用具有输入缓冲区的数据流块来协调读写器。使用
TaskScheduler.FromCurrentSynchronizationContext()
更新UI的块要多得多useful@PanagiotisKanavos,你能写下这个作为回答吗?它解决了我的问题。