0

我在 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 并运行相同的代码,其他任务永远不会获得资源来运行。

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

4

1 回答 1

0

QueuedTaskScheduler正在按设计运行。问题是它有一个固定的最大并发级别,默认设置为Environment.ProcessorCount.

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

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

var ts = new QueuedTaskScheduler(TaskScheduler.Default, int.MaxValue);
于 2012-05-14T10:13:42.377 回答