1 TaskQueue 实现Task 队列
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 队列的更多相关文章
- [转载] 基于Redis实现分布式消息队列
转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...
- TinyOS 中的 task
task 的目的 做过界面的编程的同学可能会有这种经历,界面不响应,那,其实程序总是在后台运行,但是后台可能是个for循环,那么界面的点击等事件都不能执行. 在windows界面编程中利用了事件机制来 ...
- Redis 实现队列http://igeekbar.com/igeekbar/post/436.htm
场景说明: ·用于处理比较耗时的请求,例如批量发送邮件,如果直接在网页触发执行发送,程序会出现超时 ·高并发场景,当某个时刻请求瞬间增加时,可以把请求写入到队列,后台在去处理这些请求 ·抢购场景,先入 ...
- Android之线程池深度剖析
1.线程池的引入 引入的好处: 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 使用条件: 假设在一台服务器完成一 ...
- Java 多线程 自定义线程辅助
之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...
- java多线程-线程池
线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用.因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等. 我们可以把并发执行的任务传递给一个线程池, ...
- Java并发编程:Timer和TimerTask(转载)
Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...
- Java线程池的实现
线程池的作用: 一个线程的周期分为:创建.运行.销毁三个阶段. 处理一个任务时,首先创建一个任务线程,然后执行任务,完了还要销毁线程.而线程只有处于运行状态的时候,才是真的在处理我们交给它的任务,这个 ...
- 线程池的原理及实现 (zhuan)
http://blog.csdn.net/hsuxu/article/details/8985931 ************************************************* ...
随机推荐
- Centos 7 nginx-1.12.0 配置学习(一)
[root@bogon nginx]# vim nginx.conf #user nobody; #运行用户 worker_processes ; #启动进程,通常设置成和cpu核心数相等 #全局错误 ...
- bzoj 2044 三维导弹拦截 —— 最小路径覆盖
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2044 第一问暴力 n^2 即可: 注意这道题对位置没要求!所以先按第一维排序一下即可: 然后 ...
- JSP-Runoob:JSP JavaBean
ylbtech-JSP-Runoob:JSP JavaBean 1.返回顶部 1. JSP JavaBean JavaBean是特殊的Java类,使用J ava语言书写,并且遵守JavaBean AP ...
- java将JSON字符串转换为实体类对象,基于net.sf.json实现
@SuppressWarnings("unchecked") public static <T> T jsonToObject(String jsonString, C ...
- PCB SVN 服务端VisualSVN Server与TortoiseSVN
PCB 工程系统SVN源代码招病毒破坏以后,一周时间都没有源代码同步更新了,今天终于将SVN源代码数据恢复并重建SVN服务器,这里将SVN搭建安装过程整理如下 一.服务端SVN安装 1.下载地址:ht ...
- 牛客小白月赛15 C 表单 ( map 使用)
链接:https://ac.nowcoder.com/acm/contest/917/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- C语言过时了?为什么还要推荐每一位程序员都来学一下C语言?
互联网蓬勃发展的时代,有一类人做出了巨大的贡献,这一群人被大家称之为程序员,怎样才能成为一名优秀的程序员呢,为什么每一个程序员都需要学习C语言呢? 就让我来跟大家分享分享: 在学习C/C++或者想 ...
- BZOJ DZY Loves Math系列
⑤(BZOJ 3560) $\Sigma_{i_1|a_1}\Sigma_{i_2|a_2}\Sigma_{i_3|a_3}\Sigma_{i_4|a_4}...\Sigma_{i_n|a_n}\ph ...
- Java保存错误日志信息
我们平时在撸代码的时候,有时候需要将某个代码块的具体错误信息保存到数据库或文件中,以便日后方便快速的查找问题. 使用e.printStackTrace(),我们可以将信息保存在具体的变量中,然后写入数 ...
- hbuilder中的 http://www.w3.org/TR/html4/frameset.dtd
<!-- This is the HTML 4.01 Frameset DTD, which should be used for documents with frames. This DTD ...