class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person>();
for (int i = ; i < ; i++)
list.Add(new Person("AA" + i)); TaskQueue<Person> task = new TaskQueue<Person>();
task.MaxDataCountEverySubTask = ;
task.MaxRunningSubTaskCount = ;
task.ExecuteData += task_ExecuteData;
task.TaskCompleted += task_TaskCompleted;
Console.WriteLine(DateTime.Now.ToString("mm ss fff"));
task.QueueUserTaskDataAsync(list); Console.WriteLine("主线程Ok");
Console.ReadKey();
}
public static void LongTimeMethod()
{
var list2 = new List<string>();
for (int i = ; i < ; i++)
{
list2.Add(i.ToString());
}
list2 = null;
}
static void task_ExecuteData(List<Person> executeData)
{
try
{
LongTimeMethod(); executeData.ForEach(a => Console.WriteLine("{0} {1}", a.Name, DateTime.Now.ToString("mm ss fff")));
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static void task_TaskCompleted()
{
Console.WriteLine("执行完成");
}
public class Person
{
public string Name { get; set; }
public Person(string name)
{
this.Name = name;
}
}
}
TaskQueue
    /// <summary>
/// 任务队列
/// </summary>
/// <typeparam name="T">任务要处理的数据的数据类型</typeparam>
/// 示例在末尾
public class TaskQueue<T>
{
#region 成员、属性、事件
/// <summary>
/// 数量锁
/// </summary>
private string _countLock = "LockCount";
/// <summary>
/// 总数量锁
/// </summary>
private string _countLockMain = "LockCountMain";
private bool _isAsyn = false;
/// <summary>
/// 当在分配子任务时,遇到最大可执行任务数阻塞时,线程休眠的时长。
/// </summary>
private int _sleepMilliSecondsWhenQueueSubTask = ;
/// <summary>
/// 当在分配子任务时,遇到最大可执行任务数阻塞时,线程休眠的时长。
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// value小于等于0时触发。
/// </exception>
public int SleepMilliSecondsWhenQueueSubTask
{
get { return _sleepMilliSecondsWhenQueueSubTask; }
set
{
if (value <= )
{
throw new ArgumentOutOfRangeException("value值必须大于0。");
}
_sleepMilliSecondsWhenQueueSubTask = value;
}
}
/// <summary>
/// 当在在等待子任务完成时,每次线程休眠的时长。
/// </summary>
private int _sleepMilliSecondsWhenWaitComplete = ;
/// <summary>
/// 当在在等待子任务完成时,每次线程休眠的时长。
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// value小于等于0时触发。
/// </exception>
public int SleepMilliSecondsWhenWaitComplete
{
get { return _sleepMilliSecondsWhenWaitComplete; }
set
{
if (value <= )
{
throw new ArgumentOutOfRangeException("value值必须大于0。");
}
_sleepMilliSecondsWhenWaitComplete = value;
}
}
/// <summary>
/// 允许同时执行的子任务个数
/// </summary>
private int _maxRunningThreadCount = ;
/// <summary>
/// 允许同时执行的子任务个数
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// value等于0时触发。
/// </exception>
public int MaxRunningSubTaskCount
{
get { return _maxRunningThreadCount; }
set
{
if (value <= )
{
throw new ArgumentOutOfRangeException("value值必须大于0。");
}
lock (_countLock)
{
_maxRunningThreadCount = value;
}
}
}
/// <summary>
/// 每个子任务要处理的数据个数
/// </summary>
private int _maxDataCountEverySubTask = ;
/// <summary>
/// 每个子任务要处理的数据个数
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// value等于0时触发。
/// </exception>
public int MaxDataCountEverySubTask
{
get { return _maxDataCountEverySubTask; }
set
{
if (value <= )
{
throw new ArgumentOutOfRangeException("value值必须大于0。");
}
lock (_countLock)
{
_maxDataCountEverySubTask = value;
}
}
}
/// <summary>
/// 当前已分配子任务个数
/// </summary>
private int _currentSubTaskCount = ;
/// <summary>
/// 当前已分配子任务个数
/// </summary>
public int CurrentSubTaskCount
{
get { return _currentSubTaskCount; }
}
/// <summary>
/// 当前已执行成功的子任务个数
/// </summary>
private int _currentSuccessSubTaskCount = ;
/// <summary>
/// 当前已执行成功的子任务个数
/// </summary>
public int CurrentSuccessSubTaskCount
{
get { return _currentSuccessSubTaskCount; }
}
/// <summary>
/// 当前已执行失败的线程个数
/// </summary>
private int _currentFailSubTaskCount = ;
/// <summary>
/// 当前已执行失败的线程个数
/// </summary>
public int CurrentFailSubTaskCount
{
get { return _currentFailSubTaskCount; }
} /// <summary>
/// 每个子任务执行的委托
/// </summary>
/// <param name="sender">发送者</param>
/// <param name="executeData">要处理的数据</param>
//public delegate void ExecuteDelegate(TaskQueue<T> taskQueue, List<T> executeData);
public delegate void ExecuteDelegate(List<T> executeData);
/// <summary>
/// 需要子任务处理数据时触发
/// </summary>
public event ExecuteDelegate ExecuteData;
/// <summary>
/// 触发子任务处理数据
/// </summary>
/// <param name="executeData"></param>
protected void OnExecuteData(List<T> executeData)
{
if (ExecuteData != null)
{
//ExecuteData(this, executeData);
ExecuteData(executeData);
}
}
/// <summary>
/// 所有子任务处理结束后要执行的委托
/// </summary>
/// <param name="sender">发送者</param>
//public delegate void TaskCompletedDelegate(TaskQueue<T> taskQueue);
public delegate void TaskCompletedDelegate();
/// <summary>
/// (异步模式下才会触发)所有子任务处理结束后触发
/// </summary>
public event TaskCompletedDelegate TaskCompleted;
/// <summary>
/// 通知任务队列拥有者任务已执行完成。
/// </summary>
protected void OnTaskExecuted()
{
if (TaskCompleted != null)
{
//TaskCompleted(this);
TaskCompleted();
}
}
/// <summary>
/// 任务要处理的所有数据
/// </summary>
private List<T> _taskData;
/// <summary>
/// 任务要处理的所有数据
/// </summary>
public List<T> TaskData
{
get { return _taskData; }
} #endregion #region 方法
/// <summary>
/// (异步模式)写入任务队列要处理的数据。函数会立刻返回。
/// </summary>
/// <param name="taskData">要处理的数据</param>
/// <exception cref="ArgumentNullException">
/// taskData为null时触发。
/// </exception>
///
/// <exception cref="ArgumentOutOfRangeException">
/// taskData元素个数等于0时触发。
/// </exception>
public void QueueUserTaskDataAsync(List<T> taskData)
{
_isAsyn = true;
ThreadPool.QueueUserWorkItem(QueueTask, taskData);
} /// <summary>
/// (同步模式)写入任务队列要处理的数据。函数会在所有子任务执行结束后返回。
/// </summary>
/// <param name="taskData">要处理的数据</param>
/// <exception cref="ArgumentNullException">
/// taskData为null时触发。
/// </exception>
///
/// <exception cref="ArgumentOutOfRangeException">
/// taskData元素个数等于0时触发。
/// </exception>
public void QueueUserTaskData(List<T> taskData)
{
QueueTask(taskData);
} /// <summary>
/// 写入任务队列要处理的数据
/// </summary>
/// <param name="taskData">要处理的数据</param>
/// <exception cref="ArgumentNullException">
/// taskData为null时触发。
/// </exception>
///
/// <exception cref="ArgumentOutOfRangeException">
/// taskData元素个数等于0时触发。
/// </exception>
private void QueueTask(object taskData)
{
_taskData = taskData as List<T>;
if (_taskData == null)
throw new ArgumentNullException("taskData不能为空。");
if (_taskData.Count <= )
throw new ArgumentOutOfRangeException("taskData元素个数至少有一个。");
// 初始化数据
lock (_countLock)
{
_currentSubTaskCount = _currentSuccessSubTaskCount = _currentFailSubTaskCount = ;
}
// 分配数据给子任务,直到所有数据分配完毕
do
{
// 取出子任务需处理的数据
List<T> executeData = _taskData.Take(_maxDataCountEverySubTask).ToList();
// 从总数据中移除
_taskData.RemoveRange(, executeData.Count);
// 如果正在执行的子任务达到了最大限定数目,则休眠一次
while (_maxRunningThreadCount <= _currentSubTaskCount - _currentSuccessSubTaskCount - _currentFailSubTaskCount)
{
Thread.Sleep(_sleepMilliSecondsWhenQueueSubTask);
}
// 分配子任务
ThreadPool.QueueUserWorkItem(ExecuteDataTask, executeData);
// 累计总子任务数
lock (_countLockMain)
{
_currentSubTaskCount++;
}
}
while (_taskData.Count > );
// 等待所有子任务执行结束
while (_currentSubTaskCount > _currentSuccessSubTaskCount + _currentFailSubTaskCount)
{
Thread.Sleep(_sleepMilliSecondsWhenWaitComplete);
}
// 如果是异步模式,则需要通知队列拥有者任务已完成
if (_isAsyn)
{
ThreadPool.QueueUserWorkItem(FireTaskExecuted);
}
} /// <summary>
/// 异步触发TaskExecuted事件
/// </summary>
/// <param name="state"></param>
private void FireTaskExecuted(object state)
{
// 通知队列拥有者任务已完成
OnTaskExecuted();
} /// <summary>
/// 子任务处理数据
/// </summary>
/// <param name="data">子任务所需处理数据</param>
private void ExecuteDataTask(object data)
{
bool success = true;
try
{
List<T> executeData = data as List<T>;
// 通知队列拥有者处理数据
OnExecuteData(executeData);
}
catch
{
success = false;
}
// 累计子任务运行结束的数量
if (success)
{
// 累计到成功数上
lock (_countLock)
{
_currentSuccessSubTaskCount++;
}
}
else
{
// 累计到失败数上
lock (_countLock)
{
_currentFailSubTaskCount++;
}
}
}
#endregion
} #region 示例
//static void Main(string[] args)
//{
// List<Person> list = new List<Person>() { new Person("AA"), new Person("BB"), new Person("CC") };
// TaskQueue<Person> task =new TaskQueue<Person>();
// task.ExecuteData += task_ExecuteData;
// task.TaskCompleted += task_TaskCompleted;
// task.QueueUserTaskDataAsync(list);
// Console.WriteLine("主线程Ok");
// Console.ReadKey();
//}
//static void task_ExecuteData( List<Person> executeData)
//{
// try
// {
// Thread.Sleep(3000);
// executeData.ForEach(a => Console.WriteLine(a.Name));
// }
// catch (Exception ex)
// {
// Console.WriteLine(ex.ToString());
// }
//}
//static void task_TaskCompleted()
//{
// Console.WriteLine("执行完成");
//}
//public class Person
//{
// public string Name { get; set; }
// public Person(string name)
// {
// this.Name = name;
// }
//}
#endregion

1 TaskQueue 实现Task 队列的更多相关文章

  1. [转载] 基于Redis实现分布式消息队列

    转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...

  2. TinyOS 中的 task

    task 的目的 做过界面的编程的同学可能会有这种经历,界面不响应,那,其实程序总是在后台运行,但是后台可能是个for循环,那么界面的点击等事件都不能执行. 在windows界面编程中利用了事件机制来 ...

  3. Redis 实现队列http://igeekbar.com/igeekbar/post/436.htm

    场景说明: ·用于处理比较耗时的请求,例如批量发送邮件,如果直接在网页触发执行发送,程序会出现超时 ·高并发场景,当某个时刻请求瞬间增加时,可以把请求写入到队列,后台在去处理这些请求 ·抢购场景,先入 ...

  4. Android之线程池深度剖析

    1.线程池的引入   引入的好处:   1)提升性能.创建和消耗对象费时费CPU资源   2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多.   使用条件:      假设在一台服务器完成一 ...

  5. Java 多线程 自定义线程辅助

    之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...

  6. java多线程-线程池

    线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用.因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等. 我们可以把并发执行的任务传递给一个线程池, ...

  7. Java并发编程:Timer和TimerTask(转载)

    Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...

  8. Java线程池的实现

    线程池的作用: 一个线程的周期分为:创建.运行.销毁三个阶段. 处理一个任务时,首先创建一个任务线程,然后执行任务,完了还要销毁线程.而线程只有处于运行状态的时候,才是真的在处理我们交给它的任务,这个 ...

  9. 线程池的原理及实现 (zhuan)

    http://blog.csdn.net/hsuxu/article/details/8985931 ************************************************* ...

随机推荐

  1. AngularJS入门学习

    初识: {{}}   这种双层花括号的语法称之为:插值语法:也可以说是 标识符:AngularJS 主要就是使用这种方法进行数据绑定 ng-module="name"   在ng的 ...

  2. MODULE_DEVICE_TABLE的理解【转】

    本文转载自:http://blog.csdn.net/sidely/article/details/39666471 在Linux IIC驱动中看到一段代码: static struct platfo ...

  3. java问题解读,String类为什么是final的

    一.理解final 望文生义,final意为“最终的,最后的”,我理解为“不能被改变的”,它可以修饰类.变量和方法. 所以我是否可以理解为被它所修饰的类.变量和方法都不能被改变呢?答案是”是“,因为有 ...

  4. Poj2054 color a tree && [HNOI/AHOI2018]排列

    https://zybuluo.com/ysner/note/1120723 题面 原题 某省选强化题 大致意思是给你一颗树,选父亲后才能选儿子. 每个点对答案的贡献为你在第几次选这个点 × 该点权值 ...

  5. 学习一点汇编 INT 16H指令

    转自:http://blog.pfan.cn/feling/16292.html 功能号:00H和10H 功能:从键盘读入字符 入口参数:AH          =00H—读键盘           ...

  6. Complicated Expressions(表达式转换)

    http://poj.org/problem?id=1400 题意:给出一个表达式可能含有多余的括号,去掉多余的括号,输出它的最简形式. 思路:先将表达式转化成后缀式,因为后缀式不含括号,然后再转化成 ...

  7. npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...

  8. JavaScript入门二

    ******函数****** **函数定义** //普通函数定义 function f1() { console.log("Hello word!") } //带参数的函数 fun ...

  9. Python安装distribute包

    从官网https://pypi.python.org/pypi/distribute/0.6.49#downloads上下载distribute包,解压后进入解压文件的目录下,使用 python se ...

  10. Android RecyclerView遇到notifyDataSetChanged无效时的解决方案

    一.简述 不管AbsListView(ListView.GridView)或是新出的RecyclerView,在使用notifyDataSetChanged方法更新列表数据时,一定要保证数据为同个对象 ...