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 ************************************************* ...
随机推荐
- java中不能使用小数点(.)来作为分隔符
split()括号里是一个String的参数,所以一定要符合这种:split(".")形式,即点'.'要用双引号""括起来"."在java中 ...
- 排列(permutation) 用1,2,3,…,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要 求abc:def:ghi=1:2:3。按照“abc def ghi”的格式输出所有解,每行一个解。
#include <stdio.h> #include <math.h> // 算法竞赛的目标是编程对任意输入均得到正确的结果. // 请先独立完成,如果有困难可以翻阅本书代码 ...
- 软-RAID 5组建
图文版raid5组建之软RAID [复制链接] 发表于 2007-3-6 09:19 | 来自 51CTO网页 [只看他] 楼主 硬件raid5的组建和使用,基本上说完 ...
- Codeforces Round #367 (Div. 2) 套题
吐槽:只能说是上分好场,可惜没打,唉 A:Beru-taxi (水题,取最小值) #include <cstdio> #include <cstring> #include & ...
- BigInteger、BigDecimal类的使用详解
我们都知道在java里边long算是存储长度比较大的了,但是如果有很大的数我们应该怎么处理呢,不用怕,java还为我们准备了一个BigInteger的类,那么这个类到底能存储多大的数呢,这个一时还真不 ...
- Entity Framework 4.3 中使用存储过程
尽管 Entity Framework 4.3 都已经发布了,且表示在 EF 5 中性能将会有很大提升.但很多存储过程控,始终不会放弃使用存储过程,那今天就让我们看看在 EF 4.3 中怎么使用存储过 ...
- knockjs
用VS2012建立Web站点有个新惊喜,默认加了KnockoutJS这个Javascript的MVVM模式的实现库,方便Web前端的开发 官方站点 √主页: http://www.knockoutj ...
- Boost(1.69.0) windows入门(译)
目录 Boost windows入门 1. 获得Boost源代码 2. Boost源代码组织 The Boost Distribution 3. 仅用头文件的库 Header-Only Librari ...
- aop 切面demo
/** * 必须要@Aspect 和 @Component一起使用否则没法拦截通知 * 搞了好久才明白刚刚开始以为时execution里面的配置的问题 * AOP使用很简单的 */@Aspect@Co ...
- Android 使用WebView浏览有声音或者视频的网页,关闭WebView之后,声音或者视频不停止的解决办法
笔者最近使用Eclipse开发Android移动应用app,其实有一个功能是使用Android系统自带的WebView控件加载Web页面.开发很顺利,浏览也很正常.不过有个比较特殊的一点就是加载的We ...