可控Threadpool设计
来源:互联网 发布:mac连接wifi但不能上网 编辑:程序博客网 时间:2024/06/07 03:07
AbortableThreadPool
可控Threadpool设计
我们在使用.net类库自带的threadpool的时候,很方便,但有时也会发现存在一些问题。
比如加入的任务不好控制,如果我想中止正在执行的任务,或者如果想等待threadpool 中的任务执行完成,程序再退出.基于这个问题,写了一个AbortableThreadPool类,实际项目中可以直接拿来用.
AbortableThreadPool.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Debug
{
//任务 状态
public enum WorkItemStatus
{
Completed, //完成
Queued, //入队
Executing, //执行
Aborted //中止
}
//任务
public sealed class WorkItem
{
private WaitCallback callback; //Thread pool 的回调代理
private object state; //回调参数
private ExecutionContext ctx; //与执行的逻辑线程相关的所有信息上下文
internal WorkItem(WaitCallback callback, object state, ExecutionContext ctx)
{
this.callback = callback;
this.state = state;
this.ctx = ctx;
}
internal WaitCallback Callback
{
get
{
return callback;
}
}
internal object State
{
get
{
return state;
}
}
internal ExecutionContext Context
{
get
{
return ctx;
}
}
}
//可终止线程池
public class AbortableThreadPool
{
private LinkedList<WorkItem> callbacks = new LinkedList<WorkItem>(); //任务列表
private Dictionary<WorkItem, Thread> threads = new Dictionary<WorkItem, Thread>(); //线程列表
//加入任务对列
public WorkItem QueueUserWorkItem(WaitCallback callback)
{
return QueueUserWorkItem(callback, null);
}
public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
{
if (callback == null) throw new ArgumentNullException("callback");
WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
lock (callbacks)
{
callbacks.AddLast(item);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
return item;
}
private void HandleItem(object ignored)
{
WorkItem item = null;
try
{
lock (callbacks)
{
if (callbacks.Count > 0)
{
item = callbacks.First.Value;
callbacks.RemoveFirst();
}
if (item == null)
return;
threads.Add(item, Thread.CurrentThread);
}
ExecutionContext.Run(item.Context,
delegate { item.Callback(item.State); }, null);
}
finally
{
lock (callbacks)
{
if (item != null)
threads.Remove(item);
}
}
}
//是否是可中止线程
public bool IsAbortableThread(Thread thread)
{
lock (callbacks)
{
foreach (Thread t in threads.Values)
{
if (t == thread)
return true;
}
return false;
}
}
//取消任务
public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
{
if (item == null)
throw new ArgumentNullException("item");
lock (callbacks)
{
LinkedListNode<WorkItem> node = callbacks.Find(item);
if (node != null)
{
callbacks.Remove(node);
return WorkItemStatus.Queued;
}
else if (threads.ContainsKey(item))
{
if (allowAbort)
{
threads[item].Abort();
threads.Remove(item);
return WorkItemStatus.Aborted;
}
else
return WorkItemStatus.Executing;
}
else
return WorkItemStatus.Completed;
}
}
//取消所有任务
public void CancelAll(bool allowAbort)
{
lock (callbacks)
{
callbacks.Clear();
if (allowAbort)
{
foreach (Thread t in threads.Values)
t.Abort();
}
}
}
//排队任务数
public int QueueCount
{
get { return callbacks.Count; }
}
//工作任务数
public int WorkingCount
{
get { return threads.Count; }
}
//类似Thread.Join,等待AbortableThreadPool执行完成
public void Join()
{
foreach (Thread thread in threads.Values.ToArray())
{
thread.Join();
}
}
public bool Join(int millisecondsTimeout)
{
foreach (Thread thread in threads.Values.ToArray())
{
if (!thread.Join(millisecondsTimeout))
return false;
}
return true;
}
public bool Join(TimeSpan timeout)
{
foreach (Thread thread in threads.Values.ToArray())
{
if (!thread.Join(timeout))
return false;
}
return true;
}
}
}
Debug.cs 测试代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Debug
{
class Program
{
static void Main(string[] args)
{
AbortableThreadPool abortableThreadPool = new AbortableThreadPool();
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}",abortableThreadPool.QueueCount,abortableThreadPool.WorkingCount));
WorkItem workItem1 = abortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}",abortableThreadPool.QueueCount,abortableThreadPool.WorkingCount));
WorkItem workItem2 = abortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem3 = abortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem4 = abortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem5 = abortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}",abortableThreadPool.QueueCount,abortableThreadPool.WorkingCount));
Thread.Sleep(1000);
Console.WriteLine(abortableThreadPool.Cancel(workItem1, false));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}",abortableThreadPool.QueueCount,abortableThreadPool.WorkingCount));
Thread.Sleep(1000);
Console.WriteLine(abortableThreadPool.Cancel(workItem1, true));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}",abortableThreadPool.QueueCount,abortableThreadPool.WorkingCount));
Thread.Sleep(1000);
abortableThreadPool.CancelAll(true);
abortableThreadPool.Join(); //等待所有任务退出
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", abortableThreadPool.QueueCount, abortableThreadPool.WorkingCount));
}
static void Test(object state)
{
int i = 1000;
while (i-- > 0)
{
Console.WriteLine(i);
Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(800));
}
}
}
}
测试输出:
QueueCount:0,WorkingCount:0
QueueCount:1,WorkingCount:0
QueueCount:5,WorkingCount:0
999
999
998
998
997
997
Executing
QueueCount:2,WorkingCount:3
999
996
996
995
995
994
994
999
998
997
996
Aborted
QueueCount:0,WorkingCount:4
999
993
995
998
997
998
992
994
QueueCount:0,WorkingCount:0
Press any key to continue . . .
- 可控Threadpool设计
- 可控定时任务 框架设计实现
- threadpool
- ThreadPool
- threadPool
- threadpool
- ThreadPool
- threadpool
- threadpool
- ThreadPool
- ThreadPool
- ThreadPool
- ThreadPool
- ThreadPool
- ThreadPool
- ThreadPool
- threadpool
- ThreadPool
- Action中使用getServletContext()
- tomcat启动命令
- tomcat中添加新虚拟主机
- 管理的职能
- Web Service入门
- 可控Threadpool设计
- C# UDP 入门
- 组织行为学笔记:第五章 工作满意
- 组织行为学笔记:第一章 人的主体作用
- 组织行为学笔记:第二章 社会系统
- 组织行为学笔记:第三章 激励机制
- 组织行为学笔记:第四章 对雇员的激励
- 批量更新行集(所有行的所有列(除第一列)的列值=原列值-第一行列值)
- 主板审断和主板品牌