一种简单的可控并发粒度的TaskScheduler的实现
2011-10-05 18:47
423 查看
当我们使用.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来改变调度顺序。
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来改变调度顺序。
相关文章推荐
- 一种简单线程并发控制的实现
- Winform下多语言的一种简单实现
- 【C++】单例模式的一种简单实现的模板
- .net 签名加密实现的一种简单方法
- 一种偷懒方式实现心电图(Xfermode简单应用)
- 使用Akka的Actor和Future简单地实现并发处理
- 使用Akka的Actor和Future简单地实现并发处理
- 如何实现shell并发 一个入门级可控多线程shell脚本方案
- 一种简单,快速,精准的sin/cos函数模拟,及as3实现
- Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS
- 3ff0 C语言实现一种简单的应用服务器内部数据结构的思路(二)
- 一种简单分页控件的实现
- python调用c语言函数的一种简单实现方法
- [并发并行]_[pthread]_[线程池的简单设计与实现]
- 一种简单的小型企业报表实现方式
- 一种bitset类的简单实现
- 杭电1076两种代码实现,一种方便理解一种实现简单
- Java简单实现并发编程
- 网络游戏中,玩家数据同步的一种简单实现
- 一种简单的色彩平衡算法的OPENCV实现