TPL中的等待任务以及QueuedTaskScheduler的干扰问题(来自ParallelExtensionsExtra)

时间:2012-05-14 09:22:09

标签: c# .net task-parallel-library

我遇到了与ParallelExetensionExtras一起提供的QueuedTaskScheduler的一个令人不安的问题,但我的问题是关于等待任务,任务调度程序和线程资源的相当一般。

似乎等待任务消耗资源,首先检查此示例使用默认任务调度程序,在此示例中,有一个任务长时间运行,有几个任务等待其完成,而有其他任务正在等待执行。

这里的一切运作良好,我可以看到那些等待的任务开始工作,然后在等待期间释放资源,以便其他任务也开始执行。

var taskScheduler = TaskScheduler.Default;//ts.ActivateNewQueue(0);

var longRunningTask = Task.Factory.StartNew(() => Thread.Sleep(Int32.MaxValue), CancellationToken.None, TaskCreationOptions.None, taskScheduler);

Task.Factory.StartNew(() =>
{
    Console.WriteLine("Hi from waiting task");
    longRunningTask.Wait();
}, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() =>
{
    Console.WriteLine("Hi from waiting task");
    longRunningTask.Wait();
}, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() =>
{
    Console.WriteLine("Hi from waiting task");
    longRunningTask.Wait();
}, CancellationToken.None, TaskCreationOptions.None, taskScheduler);

Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(() => Console.WriteLine("Hi"), CancellationToken.None, TaskCreationOptions.None, taskScheduler);

如果我更改前两行来执行此操作:

var ts = new QueuedTaskScheduler();
var taskScheduler = ts.ActivateNewQueue(0);

意思是,使用一个队列定义一个QueuedTaskScheduler并运行相同的代码,其他任务永远不会让资源运行。

我的问题是,如果有人碰到它之前,如果有人知道如何更改任务计划程序以释放资源以等待任务。

1 个答案:

答案 0 :(得分:0)

QueuedTaskScheduler的行为符合设计。问题是它具有固定的最大并发级别,默认设置为Environment.ProcessorCount

因此,假设您没有更改默认值,4核计算机上最多将有4个正在运行的任务。

要解决此问题,您可以在不同的调度程序上运行长时间运行的任务(理想情况下,支持TaskCreationOptions.LongRunning的调度程序,如Default),或者只设置最大并发级别案例到最大值:

var ts = new QueuedTaskScheduler(TaskScheduler.Default, int.MaxValue);