如何使用 QueuedTaskScheduler 确定嵌套任务的优先级?

How to prioritize nested tasks using a QueuedTaskScheduler?

我正在使用 ParallelExtensionsExtras 中的 QueuedTaskScheduler 来安排任务 T、A 和 B。QueuedTaskScheduler 设置为仅使用 1 个线程。任务 A 和 B 只休眠 2000 毫秒。任务 T 启动 A 和 B。

我正在使用两个队列:q1(优先级 1)和 q2(优先级 2)。据我了解,这意味着安排在 q1 上的任务优先于安排在 q2 上的任务。任务 T 和 A 在 q1 上启动,任务 B 在 q2 上启动。启动A和B后,T等待他们完成。

我希望先启动 A,然后启动 B,但是,顺序完全由 A 和 B 传递给 Task.WaitAll 函数的顺序决定。

如果我没有将 A 和 B 作为嵌套任务(从 T)启动,则顺序符合预期。

为什么启动嵌套任务时,QueuedTaskScheduler 没有按预期工作?

void Main()
{
    var qts = new QueuedTaskScheduler(TaskScheduler.Default, 1);
    var scheduler1 = qts.ActivateNewQueue(1);
    var scheduler2 = qts.ActivateNewQueue(2);

    Task T = new Task(() =>
    {
        var B = slowTask(scheduler2, "B");
        var A = slowTask(scheduler1, "A");

        Task.WaitAll(A, B);
    });
    T.Start(scheduler1);

    Task.WaitAll(T);
}

private Task slowTask(TaskScheduler scheduler, string name)
{
    var t = new Task(() =>
        {
            Console.WriteLine($"starting {name}");
            Thread.Sleep(2000);
        }, CancellationToken.None, TaskCreationOptions.None);

    t.Start(scheduler);

    return t;
}

我检查了 Task.WaitAll 的实现。它将在尚未开始的任务上使用自己的线程(内联)。它将从后到前循环遍历任务数组,这就是为什么在我的情况下 B 在 A 之前启动。因此,如果您想确保始终先启动更高优先级的任务,请对传递给 [=14 的任务数组进行排序=] 从低到高优先级。

请注意,如果可用线程数大于1,则未内联的任务将按预期顺序(根据优先级)进行调度。