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

时间:2016-05-17 09:51:55

标签: c# multithreading task-parallel-library parallel-extensions

我正在使用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;
}

1 个答案:

答案 0 :(得分:0)

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

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