当我们使用.net 4.0中的任务并行库的时候,有时候我们是需要自己控制并发粒度(调度线程数)的,这个时候往往就需要我们自己写TaskScheduler了,一个简单的实现如下:

View Code

public sealed class SimpleTaskScheduler : TaskScheduler, IDisposable
{
    BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
    List<Thread> _threads = new List<Thread>();

public SimpleTaskScheduler(int initNumberOfThreads = 3)
    {
        if (initNumberOfThreads < 1)
            throw new ArgumentOutOfRangeException();

_threads.AddRange(Enumerable.Range(0, initNumberOfThreads).Select(_ => CreateThread()));
    }

Thread CreateThread()
    {
        var thread = new Thread(() =>
        {
            foreach (var t in _tasks.GetConsumingEnumerable())
            {
                TryExecuteTask(t);
            }
        });

thread.IsBackground = true;
        thread.Start();
        return thread;
    }

protected override IEnumerable<Task> GetScheduledTasks()
    {
        //这个函数好像没有调过,返回null也不影响功能
        return _tasks.ToArray();
    }

protected override void QueueTask(Task task)
    {
        _tasks.Add(task);
    }

protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        return TryExecuteTask(task);
    }

public override int MaximumConcurrencyLevel { get { return _threads.Count; } }

#region IDisposable 成员

public void Dispose()
    {
        if (_tasks == null)        //防止重入
            return;

_tasks.CompleteAdding();
        _threads.ForEach(t => t.Join());

_tasks.Dispose();
        _tasks = null;
    }

#endregion
}

这个类实现并不复杂,但其实用得还是比较多的,这里记录一下,以备后续查询。

PS:当前在Parallel.ForEach或Parallel.For等数据并发函数中可以通过ParallelOptions.MaxDegreeOfParallelism来控制并发粒度,但无法控制调度顺序。也可以通过类似这样的TaskScheduler来改变调度顺序。

转载于:https://www.cnblogs.com/TianFang/archive/2011/10/05/2199526.html

一种简单的可控并发粒度的TaskScheduler的实现相关推荐

  1. 9种高性能可用高并发的技术架构

    9种高性能可用高并发的技术架构 1.分层 分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对简单并比较单一的职责,然后通过上层对下层的依赖和调度组成一个 ...

  2. EasyBridge:一种简单的js-bridge设计方案

    EasyBridge是一个简单易用的js-bridge的工具库,提供了日常开发中,JavaScript与Java之间通讯的能力,与其他常见的js-bridge工具库实现方案不同,EasyBridge具 ...

  3. C++中Future和Promise的一种简单实现

    女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...

  4. 中的listeners_C++中Future和Promise的一种简单实现

    女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...

  5. java按两列输出_有没有一种简单的方法可以将两列输出到Java中的控制台? - java...

    如标题所述,是否有一种简单的方法可以将两列输出到Java中的控制台? 我知道\t,但是在使用printf时,我还没有找到基于特定列进行空间分配的方法. 参考方案 使用宽度和精度说明符,将其设置为相同的 ...

  6. 一种简单的图形旋转算法

    图形旋转好玩又有实用性, 这里介绍一种简单的图形旋转算法. 具体步骤如下: 1. 首先将原图和旋转图的坐标原点都变换到图形的中心位置处. 2. 历遍旋转图形中的每一个pixel, 将pixel的坐标( ...

  7. 让 AI 看懂你的心情,并推荐应景的音乐,以一种简单的实现

    一种(简单的)基于心情的音乐推荐系统 项目完整源码:https://github.com/cdfmlr/murecom-verse-1 你什么时候听音乐?快乐的时候,悲伤的时候,兴奋的时候,失落的时候 ...

  8. CSS里总算是有了一种简单的垂直居中布局的方法了

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><me ...

  9. ICCV2021 Oral SimROD:简单高效的数据增强!华为提出了一种简单的鲁棒目标检测自适应方法...

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨小马 来源丨我爱计算机视觉 ▊ 写在前面 本文提出了一种简单有效的鲁棒目标检测无监督自适应方法( ...

最新文章

  1. 十一运夺金基础数据采集工具
  2. 【青少年编程(第30周)】关于青少年编程能力等级测评的科普!
  3. LeetCode实战:快乐数
  4. 数据库基础笔记(MySQL)7 —— 存储引擎和视图 ( 完结撒花 )
  5. python导入模块报错syntaxerror_SyntaxError: invalid syntax python错误解决方法
  6. 微信小程序搜索功能!附:小程序前端+PHP后端
  7. linux grep 点号的匹配
  8. Spring-mybatis 抽取 baseDao。
  9. vs code python_用VScode配置Python开发环境
  10. 求凸函数极值 CSF迭代法(雾)
  11. 第11章 樱花树(《C和C++游戏趣味编程》配套教学视频)
  12. 洛谷——P2077 红绿灯(解法2)
  13. 用Python解析XMind
  14. combres java_ASP.NET MVC3 Combres错误:'System.Web.Mvc.UrlHelper'不包含'CombresLink'的定义
  15. php中控车牌识别push协议,2、实时车牌识别上传及返回
  16. paxos算法例子图解
  17. 马尔可夫链预测模型的应用——以安徽各城市人均GDP预测为例
  18. CPU,GPU,TPU,NPU都是什么?
  19. Openstack 经典面试问题和解答
  20. 什么是overlay?

热门文章

  1. 【Matplotlib】 标注一些点
  2. 域本地组,全局组,通用组的应用
  3. 谁说大学生找工作难?鄙视说这样话的人!!
  4. lxml读取本地html文件,如何使用Python和lxml来解析本地html文件?
  5. linux系统rar命令行,Linux下rar命令详解
  6. wordpress 运行_如何为您的教室设置和运行WordPress
  7. 如何在Linux上安装设备驱动程序
  8. github 创始人_GitHub联合创始人Scott Chacon的视频采访,探讨代码之外的未来
  9. 值不值 | 三分钟搞定jpa?值不值!
  10. Bootstrap3 按钮状态提示