【问题标题】:.Net TPL: Limited Concurrency Level Task scheduler with task priority?.Net TPL:具有任务优先级的有限并发级别任务调度程序?
【发布时间】:2012-02-16 17:23:20
【问题描述】:

我目前正在使用此处详细介绍的 LimitedConcurrencyLevelTask​​Scheduler http://msdn.microsoft.com/en-us/library/ee789351.aspx

我想加强这一点,以便可以为个人任务分配优先级。这些优先级不需要映射到线程优先级。它应该只影响任务启动的顺序。

有谁知道这样一个任务调度器的例子吗? (很多日程安排的事情都在我头上,所以如果有现成的解决方案那就太好了)

【问题讨论】:

  • 该调度程序使用 LinkedList 作为队列。尝试将其更改为 SortedList 其中 T 是一个结构,其中包含一个 Task 和一个整数作为优先级,并在 T.Priority 上对列表进行排序。
  • @IgbyLargeman - SortedList 可能不是一个理想的解决方案 - 键(优先级)必须是唯一的。大多数优先级系统只有几个级别,并且允许为多个项目分配相同的优先级
  • 这是个坏主意。具有内部一组(数组)队列的队列 - 每个优先级一个 - 是一种更好的方法。优先级不是唯一的,并且仅限于少数几个。也不要使用链表——我有一个“队列”,它在内部使用 4096 个元素的数组,外加 opointers。更少的分配 - 项目从前面的“页面”中删除,添加到 nd。更少的分配,更少的垃圾收集。
  • @Damien_The_Unbeliever:说得好。不知何故,我在想 SortedList 可能有重复的键。高级时刻...
  • 如果您对带有仅异步 API 的 PrioritySemaphore 感兴趣,请查看 here

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


【解决方案1】:

Parallel Extensions Extras Samples. 已经提供了这样的调度程序,QueuedTaskScheduler。此调度程序提供优先级、并发限制、公平性和对所使用线程的类型和优先级的细粒度控制。当然,您不必使用或配置您不需要的功能。

Stephen Toub 在 Parallel Extensions Extras here 中提供了各种调度程序的简要说明

要使用 QueuedTaskScheduler,您需要使用所需的优先级调用其 ActivateNewQueue 方法。此方法返回由父 TaskScheduler 管理的新 TaskScheduler 派生 Queue 对象。所有使用特定队列的任务都由父 TaskScheduler 根据其优先级进行调度。

以下代码创建一个最大并发级别为 4 的调度程序,两个优先级队列,并在第一个队列上调度一个任务:

QueuedTaskScheduler qts = new QueuedTaskScheduler(TaskScheduler.Default,4);
TaskScheduler pri0 = qts.ActivateNewQueue(priority: 0);
TaskScheduler pri1 = qts.ActivateNewQueue(priority: 1);

Task.Factory.StartNew(()=>{ }, 
                      CancellationToken.None, 
                      TaskCreationOptions.None, 
                      pri0);

【讨论】:

    【解决方案2】:

    对任务列表使用某种排序或优先级的数据结构。然后创建您自己的优先级添加。这可能不如其他人好,但它会优先考虑任务列表。您可以在那里重用 99% 的代码。只需将 LinkedList 替换为排序列表或使用 LINQ 排序并编写一个方法 add 优先。

    【讨论】:

      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2010-09-07
      • 1970-01-01
      相关资源
      最近更新 更多