- 浏览: 724758 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1081)
- [网站分类]1.首页原创精华.NET区(包含架构设计、设计模式)(对首页文章的要求:原创、高质量、经过认真思考并精心写作) (0)
- [网站分类]2..NET新手区(用于发表不合适发表在首页的.NET技术文章,包括小经验、小技巧) (1)
- [网站分类]3.非技术区(技术之外的文章,但不要涉及任何政治内容) (0)
- [网站分类]4.其他技术区 (0)
- [网站分类]5.企业信息化 (0)
- [网站分类]6.读书心得区(技术书籍阅读心得、书籍推荐) (0)
- [网站分类]7.提问区(.NET技术方面的提问) (2)
- [网站分类]8.技术转载区(.NET技术文章转载, 请注明原文出处) (0)
- [网站分类]9.求职招聘区(个人求职、企业招聘) (0)
- [网站分类]Dottext区 (0)
- [网站分类]GIS技术 (0)
- [网站分类]IT英才专区(IT职场交流) (0)
- [网站分类]SharePoint (0)
- [网站分类]博客园.NET俱乐部(俱乐部组织与活动方面的文章) (0)
- [网站分类]软件发布区(发布自己开发的代码、软件) (0)
- [网站分类]网站管理区(网站管理方面的疑问、建议、意见, 寻求管理员帮助) (0)
- [网站分类]业界新闻 (1)
- 技术 (1)
- [随笔分类]生活感悟 (10)
- [随笔分类]C# (30)
- [随笔分类]AjaxPro教程 (3)
- [发布至博客园首页] (5)
- [随笔分类]简历 (0)
- [随笔分类]Linux (2)
- [随笔分类]技术聚会 (2)
- [随笔分类]ORM (1)
- [随笔分类]php (1)
- [随笔分类]创业 (1)
- [随笔分类]奇技淫巧 (1)
- [随笔分类]计划 (1)
- [随笔分类]架构&分层 (1)
- [随笔分类]整合行销 (1)
- [随笔分类]mac (1)
- [网站分类].NET新手区 (45)
- [网站分类]非技术区 (5)
- [网站分类]招聘区 (0)
- [随笔分类]单元测试 (1)
- [网站分类]其他技术区 (3)
- [网站分类]代码与软件发布 (6)
- [网站分类]提问区 (24)
- [随笔分类]ASP.NET (2)
- [随笔分类]FAQ (12)
- [随笔分类]开发人员工具 (1)
- [随笔分类]朗志轻量级项目管理解决方案 (1)
- [网站分类]读书区 (1)
最新评论
-
天使建站:
写和乱七八糟的 不知道从哪复制过来的 还是看这里吧j ...
jquery数组 -
hyn450:
你好,我最近也想了解一下竞争情报。不知道能不能交流一下呢 ?
最近的工作 -
lattimore:
这个连接打不开了阿!
使用vnc连ubuntu desktop -
MZhangShao:
奉劝你一句,以后在Ubuntu 用apt-get安装成功的软件 ...
关于xrdp的安装设置 -
f002489:
strftime
python下datetime类型的转换
在自制线程池2中讲到了,实现了线程池中的一些不足之处,
今天我在前面的基础上改进了以下内容,
A。Thread.Suspend和Thread.Resume方法在2.0已经被Obslete,因此改用了其它方法来实现
B。原先新建的线程在空闲没有任务时是处于Suspend状态,如果起动了100个线程,完成任务后还是有100个线程存在,现在加入了策略,当线程空闲60s没有被复用(重新获得任务)则该线程自动销毁。
C。更新了同步的方法,比前面的实现好多了,不过肯定还是存在些问题,同步,竞争读写,线程安全这些内容还是比较糊,在今后的实践中慢慢改进吧
D。使线程池可以实例化,这样可以创建多个专用的线程池,这样的好处是,一些任务对执行的时间没有要求,但是希望占用的资源低,我们可以给该线程池设定最大允许一个线程长时间执行这项工作,而另外的线程池是一些短时间的密集型请求,我们可以设定同时400个线程运行,同时将它的线程空闲注销时间设的短一些,以增强响应的能力。
该版本还存在的问题
A.代码不够清楚,多余的代码仅是注释掉了,并没有删除,这样以后看起来可以给自己一些思路,自己是怎么一步一步改过来的,不知道这个算不算是一个坏习惯,我也想把原先不用的代码删除了,但我怕以后自己都看不懂现在演化过来的代码是什么意思,大家有没有这样的情况
B.各个实例化的线程池之间无法共享复用空闲线程,这个是一个很大的问题,但是我还没想到实现的方法,为了这个问题想了一天多了。
C。再将SmartThreadPool中一些实用的功能补充进来。
另外发现
这个是实现的代码
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Amib.Threading.Internal;
using Rhino.Commons;
namespace ThreadPool2
{
public delegate object WaitCallback2(object state);
public delegate void SuccCallback(object state, object result);
public delegate void ErrCallback(object state);
/// <summary>
/// 此线程池的作用是将某一类特殊的任务交给此线程池执行,
/// 可以设定该线程池的最大线程数,
/// 这类线程池的优点时,占用的资源少,优先级低,
/// 适合于执行任务需要长期执行,不考虑时间因素的任务
/// 同时根据在传入线程池时的标记key,可以Aborted指定任务,
/// 若该任务正在执行或尚在执行队列中
/// </summary>
public class MyThreadPool2
{
/// <summary>
/// 任务执行队列
/// </summary>
//static ThreadSafeQueue<WorkerThread> queue = new ThreadSafeQueue<WorkerThread>();
List<WorkerThread> queue = new List<WorkerThread>();
/// <summary>
/// 目前暂定为只使用一个线程,以免耗近资源
/// </summary>
SynchronizedDictionary<string, WorkerThread> dict = new SynchronizedDictionary<string, WorkerThread>();
private object state;
AutoResetEvent wait = new AutoResetEvent(false);
AutoResetEvent wait2 = new AutoResetEvent(false);
private int MaxLimitedTime { get; set; }
private bool IsLimitedExecTime { get; set; }
//private static int _maxThreadNum = 1;
private int MaxThreadNum
{
//get { return _maxThreadNum; }
//set { _maxThreadNum = value; }
get;
set;
}
private MyThreadPool2()
{
//System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000,true);
//SetMaxThreadNum(2);
//SetMaxExecTime(false, 10000);
}
/// <summary>
/// 设置专用线程池的初始参数
/// </summary>
/// <param name="num">线程池的最大线程数,最小为1</param>
/// <param name="b">是否起用限制最大单个任务执行时间设定</param>
/// <param name="time">单个任务执行的最大时间</param>
public MyThreadPool2(int num, bool b, int time)
{
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000, true);
if (num < 1)
num = 1;
MaxThreadNum = num;
IsLimitedExecTime = b;
MaxLimitedTime = time;
if (IsLimitedExecTime)
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state,
MaxLimitedTime, true);
}
/// <summary>
/// 定时将队列中的数据装载到线程中执行,如果还没有到达最大线程数还有任务则创建线程
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
private void aa(object state, bool timedOut)
{
lock(WorkerThread.Manual){
WorkerThread.Manual.Reset();
lock (queue)
{
//判断任务队列中有无积压的任务且有无空闲的线程,如果符合上述条件则执行之
List<string> removeKey = new List<string>();
List<WorkerThread> newTask = new List<WorkerThread>();
List<string> tasks = new List<string>();
//Dictionary<string,WorkerThread> addDict=new Dictionary<string, WorkerThread>();
foreach (var kvp in dict)
{//kvp.Value.ThreadState == ThreadState.Unstarted ||
//if (kvp.Value.Thread.ThreadState == ThreadState.Suspended)
//将不活动的线程记录下来并移除
if (!kvp.Value.Thread.IsAlive)
tasks.Add(kvp.Key);
//将活动且空闲的线程赋于新的任务
if (kvp.Value.Thread.IsAlive == true && kvp.Value.CurrentThreadState == WorkerThreadState.Idle)
{
//dict.Remove(kvp.Key);//cancle because of lock
WorkerThread a = queue.FirstOrDefault();
if (a != null)
{
removeKey.Add(kvp.Key);
//addDict.Add(a.Key, kvp.Value.Change(a));
newTask.Add(kvp.Value.Change(a));
//a.Thread = kvp.Value.Thread;
//newTask.Add(a);
queue.RemoveAt(0);
//dict.Add(a.Key, kvp.Value.Change(a));//cancle because of lock
//将参数加到线程中,并改变线程的状态
//dict[a.Key].Thread.Resume();
}
else
break;
//else
//{
// System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state,
// 2000, true);
// return;
//}
}
}
tasks.ForEach(t =>
{
dict.Remove(t);
Debug.WriteLine("移除销毁线程对应的dict中的键值项,key="+t);
});
removeKey.ForEach(t => dict.Remove(t));
newTask.ForEach(t =>
{
Debug.WriteLine("复用线程用于执行新任务"+t.Key);
dict.Add(t.Key, t);
t.StartExecTime = DateTime.Now;
t.Auto.Set();
//t.CurrentThreadState = WorkerThreadState.Busy;
//t.Thread.Resume();
});
while (queue.Count > 0 && dict.Count < MaxThreadNum)
{
//未到线程池最大池程数时,增加线程
WorkerThread b = queue.FirstOrDefault();
if (b != null)
{
queue.RemoveAt(0);
//Thread thd = new Thread(new ThreadStart(b.Exec));
//thd.Priority = ThreadPriority.Lowest;
//dict.Add(b.Key, thd);
//thd.Start();
WorkerThread wt = new WorkerThread();
wt.Start(b);
dict.Add(wt.Key, wt);
wt.Thread.Start();
Debug.WriteLine("新建线程用于执行新任务"+ wt.Key);
//将参数加到线程中,并改变线程的状态
}
}
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000,
true);
}
WorkerThread.Manual.Set();
}
}
private void SetMaxThreadNum(int num)
{
if (num < 1)
num = 1;
MaxThreadNum = num;
}
private WorkerThread FindSpecificWorkerThreadByKey(string key)
{
WorkerThread wt;
dict.TryGetValue(key, out wt);
return wt;
}
/// <summary>
/// 设定单线程允许执行任务的最长时间,该方法不能在运行时改变,须事前设定
/// </summary>
/// <param name="b"></param>
/// <param name="time"></param>
[Obsolete("abandon")]
private void SetMaxExecTime(bool b, int time)
{
IsLimitedExecTime = b;
MaxLimitedTime = time;
if (IsLimitedExecTime)
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state,
MaxLimitedTime, true);
}
/// <summary>
/// 当任务执行超时时,注销该线程
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
private void bb(object state, bool timedOut)
{
lock (WorkerThread.Manual)
{
WorkerThread.Manual.Reset();
//lock (obj)
lock (dict.SyncRoot)
{
List<string> temp = new List<string>();
foreach (var kvp in dict)
{
if (kvp.Value.CurrentThreadState==WorkerThreadState.Busy &&DateTime.Now.Subtract(kvp.Value.StartExecTime).TotalMilliseconds > MaxLimitedTime)
{
temp.Add(kvp.Key);
}
}
foreach (var s in temp)
{
Debug.WriteLine("key="+s+"的任务超时,执行该任务的线程将被销毁");
_Aborted(s);
}
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state, MaxLimitedTime, true);
}
WorkerThread.Manual.Set();
}
}
public void Aborted(string key)
{
lock (WorkerThread.Manual)
{
WorkerThread.Manual.Reset();
_Aborted(key);
WorkerThread.Manual.Set();
}
}
private void _Aborted(string key)
{
lock (queue)
{
//任务如果还在队列中则删除该任务
int index = queue.FindIndex(t => t.Key == key);
if (index > -1)
{
queue.RemoveAt(index);
Debug.WriteLine("从任务队列中移除指定key="+key+"的任务");
}
}
//lock (dict.SyncRoot)
//{
#region old way now extract method FindSpecificWorkerThreadByKey to split this
//WorkerThread v;
//if (dict.TryGetValue(key, out v))
//{
// v.Thread.Abort();
// //在调用Abort方法时,在指定线程上引发ThreadAbortException。以开始终止此线程的
// //过程。ThreadAbortException是—个可以由应用程序代码捕获的特殊异常,但除非调用
// //ResetAbort,否则会在catch块的结尾再次引发它。ResetAbod可以取消Abort的请求,并
// //阻止ThreadAbortException终止此线程。但是,线程不一定会立即中止,或者根本不中止。
// //如果线程在作为中止过程的一部分被调用的finally块中做非常大量的计算,从而无限期延
// //迟中止操作,则会发生这种情况。若要确保线程已经终止,请在调用Abort之后对线程调
// //用Join方法。
// v.Thread.Join();
// dict.Remove(key);
//}
#endregion
WorkerThread v = FindSpecificWorkerThreadByKey(key);
//没有发现指定key的线程表示,对应该key的任务已经执行完了,不需要再来取消该任务
//或者指的key的线程虽然还在但它的状态已变为suspended,任务已完成,将等待下一个任务,实际不需要终止该线程
//只有但指定的key的任务在执行时才删除
//if (v != null && v.Thread.ThreadState != ThreadState.Suspended)
if (v != null && v.CurrentThreadState == WorkerThreadState.Busy)
{
dict.Remove(key);
/*
在调用Abort方法时,在指定线程上引发ThreadAbortException。以开始终止此线程的
过程。ThreadAbortException是—个可以由应用程序代码捕获的特殊异常,但除非调用
ResetAbort,否则会在catch块的结尾再次引发它。ResetAbod可以取消Abort的请求,并
阻止ThreadAbortException终止此线程。但是,线程不一定会立即中止,或者根本不中止。
如果线程在作为中止过程的一部分被调用的finally块中做非常大量的计算,从而无限期延
迟中止操作,则会发生这种情况。若要确保线程已经终止,请在调用Abort之后对线程调
用Join方法。
*/
v.Thread.Abort();
v.Thread.Join();
Debug.WriteLine("销毁正在执行Key="+key+"的任务的线程");
if (v.ErrorCallback != null)
{
v.ErrorCallback(v.State);
//最后完成任务的时间
v.EndExecTime = DateTime.Now;
}
}
//}
//wait.Set();
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, string key, SuccCallback succ, ErrCallback err)
{
WorkerThread p = new WorkerThread()
{
WaitCallback = callback,
State = state,
Key = key,
ErrorCallback = err,
SuccessCallback = succ
};
//queue.Enqueue(p);
lock (queue)
{
queue.Add(p);
//Monitor.Pulse(queue);
}
wait.Set();
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, SuccCallback succ, ErrCallback err)
{
QueueUserWorkItem(callback, state, System.Guid.NewGuid().ToString(), succ, err);
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, string key)
{
//WorkerThread p = new WorkerThread()
// {
// WaitCallback = callback,
// State = state,
// Key = key
// };
////queue.Enqueue(p);
//queue.Add(p);
//wait.Set();
QueueUserWorkItem(callback, state, key, null, null);
}
public void QueueUserWorkItem(WaitCallback2 callback, object state)
{
QueueUserWorkItem(callback, state, System.Guid.NewGuid().ToString());
}
}
public enum WorkerThreadState : byte
{
None = 0,
Busy = 1,
Idle = 2
}
public class WorkerThread
{
public AutoResetEvent Auto = new AutoResetEvent(false);
public static ManualResetEvent Manual = new ManualResetEvent(true);
public WorkerThreadState CurrentThreadState { get; set; }
public DateTime StartExecTime { get; set; }
public DateTime EndExecTime { get; set; }
public Thread Thread { get; set; }
public string Key { get; set; }
public WaitCallback2 WaitCallback { get; set; }
public SuccCallback SuccessCallback { get; set; }
public ErrCallback ErrorCallback { get; set; }
public Object State { get; set; }
public void Exec()
{
while (true)
{
this.CurrentThreadState = WorkerThreadState.Busy;
if (this.SuccessCallback != null)
this.SuccessCallback(this.State, this.WaitCallback(this.State));
else
this.WaitCallback(this.State);//如何将执行的结果返回,目前是通过SuccessCallback将结果作为参数返回,如果没有使用SuccessCallback将不能返回执行的结果
this.EndExecTime = DateTime.Now;
//如何将任务执行的起讫时间发给任务
this.CurrentThreadState = WorkerThreadState.Idle;
//this.Thread.Suspend();
//等待60s如果在此期间未接收到新的任务该线程就退出
if (!Auto.WaitOne(60 * 1000, false))
break;
Manual.WaitOne();
}
Debug.WriteLine("线程销毁");
}
public WorkerThre
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Amib.Threading.Internal;
using Rhino.Commons;
namespace ThreadPool2
{
public delegate object WaitCallback2(object state);
public delegate void SuccCallback(object state, object result);
public delegate void ErrCallback(object state);
/// <summary>
/// 此线程池的作用是将某一类特殊的任务交给此线程池执行,
/// 可以设定该线程池的最大线程数,
/// 这类线程池的优点时,占用的资源少,优先级低,
/// 适合于执行任务需要长期执行,不考虑时间因素的任务
/// 同时根据在传入线程池时的标记key,可以Aborted指定任务,
/// 若该任务正在执行或尚在执行队列中
/// </summary>
public class MyThreadPool2
{
/// <summary>
/// 任务执行队列
/// </summary>
//static ThreadSafeQueue<WorkerThread> queue = new ThreadSafeQueue<WorkerThread>();
List<WorkerThread> queue = new List<WorkerThread>();
/// <summary>
/// 目前暂定为只使用一个线程,以免耗近资源
/// </summary>
SynchronizedDictionary<string, WorkerThread> dict = new SynchronizedDictionary<string, WorkerThread>();
private object state;
AutoResetEvent wait = new AutoResetEvent(false);
AutoResetEvent wait2 = new AutoResetEvent(false);
private int MaxLimitedTime { get; set; }
private bool IsLimitedExecTime { get; set; }
//private static int _maxThreadNum = 1;
private int MaxThreadNum
{
//get { return _maxThreadNum; }
//set { _maxThreadNum = value; }
get;
set;
}
private MyThreadPool2()
{
//System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000,true);
//SetMaxThreadNum(2);
//SetMaxExecTime(false, 10000);
}
/// <summary>
/// 设置专用线程池的初始参数
/// </summary>
/// <param name="num">线程池的最大线程数,最小为1</param>
/// <param name="b">是否起用限制最大单个任务执行时间设定</param>
/// <param name="time">单个任务执行的最大时间</param>
public MyThreadPool2(int num, bool b, int time)
{
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000, true);
if (num < 1)
num = 1;
MaxThreadNum = num;
IsLimitedExecTime = b;
MaxLimitedTime = time;
if (IsLimitedExecTime)
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state,
MaxLimitedTime, true);
}
/// <summary>
/// 定时将队列中的数据装载到线程中执行,如果还没有到达最大线程数还有任务则创建线程
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
private void aa(object state, bool timedOut)
{
lock(WorkerThread.Manual){
WorkerThread.Manual.Reset();
lock (queue)
{
//判断任务队列中有无积压的任务且有无空闲的线程,如果符合上述条件则执行之
List<string> removeKey = new List<string>();
List<WorkerThread> newTask = new List<WorkerThread>();
List<string> tasks = new List<string>();
//Dictionary<string,WorkerThread> addDict=new Dictionary<string, WorkerThread>();
foreach (var kvp in dict)
{//kvp.Value.ThreadState == ThreadState.Unstarted ||
//if (kvp.Value.Thread.ThreadState == ThreadState.Suspended)
//将不活动的线程记录下来并移除
if (!kvp.Value.Thread.IsAlive)
tasks.Add(kvp.Key);
//将活动且空闲的线程赋于新的任务
if (kvp.Value.Thread.IsAlive == true && kvp.Value.CurrentThreadState == WorkerThreadState.Idle)
{
//dict.Remove(kvp.Key);//cancle because of lock
WorkerThread a = queue.FirstOrDefault();
if (a != null)
{
removeKey.Add(kvp.Key);
//addDict.Add(a.Key, kvp.Value.Change(a));
newTask.Add(kvp.Value.Change(a));
//a.Thread = kvp.Value.Thread;
//newTask.Add(a);
queue.RemoveAt(0);
//dict.Add(a.Key, kvp.Value.Change(a));//cancle because of lock
//将参数加到线程中,并改变线程的状态
//dict[a.Key].Thread.Resume();
}
else
break;
//else
//{
// System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state,
// 2000, true);
// return;
//}
}
}
tasks.ForEach(t =>
{
dict.Remove(t);
Debug.WriteLine("移除销毁线程对应的dict中的键值项,key="+t);
});
removeKey.ForEach(t => dict.Remove(t));
newTask.ForEach(t =>
{
Debug.WriteLine("复用线程用于执行新任务"+t.Key);
dict.Add(t.Key, t);
t.StartExecTime = DateTime.Now;
t.Auto.Set();
//t.CurrentThreadState = WorkerThreadState.Busy;
//t.Thread.Resume();
});
while (queue.Count > 0 && dict.Count < MaxThreadNum)
{
//未到线程池最大池程数时,增加线程
WorkerThread b = queue.FirstOrDefault();
if (b != null)
{
queue.RemoveAt(0);
//Thread thd = new Thread(new ThreadStart(b.Exec));
//thd.Priority = ThreadPriority.Lowest;
//dict.Add(b.Key, thd);
//thd.Start();
WorkerThread wt = new WorkerThread();
wt.Start(b);
dict.Add(wt.Key, wt);
wt.Thread.Start();
Debug.WriteLine("新建线程用于执行新任务"+ wt.Key);
//将参数加到线程中,并改变线程的状态
}
}
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000,
true);
}
WorkerThread.Manual.Set();
}
}
private void SetMaxThreadNum(int num)
{
if (num < 1)
num = 1;
MaxThreadNum = num;
}
private WorkerThread FindSpecificWorkerThreadByKey(string key)
{
WorkerThread wt;
dict.TryGetValue(key, out wt);
return wt;
}
/// <summary>
/// 设定单线程允许执行任务的最长时间,该方法不能在运行时改变,须事前设定
/// </summary>
/// <param name="b"></param>
/// <param name="time"></param>
[Obsolete("abandon")]
private void SetMaxExecTime(bool b, int time)
{
IsLimitedExecTime = b;
MaxLimitedTime = time;
if (IsLimitedExecTime)
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state,
MaxLimitedTime, true);
}
/// <summary>
/// 当任务执行超时时,注销该线程
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
private void bb(object state, bool timedOut)
{
lock (WorkerThread.Manual)
{
WorkerThread.Manual.Reset();
//lock (obj)
lock (dict.SyncRoot)
{
List<string> temp = new List<string>();
foreach (var kvp in dict)
{
if (kvp.Value.CurrentThreadState==WorkerThreadState.Busy &&DateTime.Now.Subtract(kvp.Value.StartExecTime).TotalMilliseconds > MaxLimitedTime)
{
temp.Add(kvp.Key);
}
}
foreach (var s in temp)
{
Debug.WriteLine("key="+s+"的任务超时,执行该任务的线程将被销毁");
_Aborted(s);
}
System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state, MaxLimitedTime, true);
}
WorkerThread.Manual.Set();
}
}
public void Aborted(string key)
{
lock (WorkerThread.Manual)
{
WorkerThread.Manual.Reset();
_Aborted(key);
WorkerThread.Manual.Set();
}
}
private void _Aborted(string key)
{
lock (queue)
{
//任务如果还在队列中则删除该任务
int index = queue.FindIndex(t => t.Key == key);
if (index > -1)
{
queue.RemoveAt(index);
Debug.WriteLine("从任务队列中移除指定key="+key+"的任务");
}
}
//lock (dict.SyncRoot)
//{
#region old way now extract method FindSpecificWorkerThreadByKey to split this
//WorkerThread v;
//if (dict.TryGetValue(key, out v))
//{
// v.Thread.Abort();
// //在调用Abort方法时,在指定线程上引发ThreadAbortException。以开始终止此线程的
// //过程。ThreadAbortException是—个可以由应用程序代码捕获的特殊异常,但除非调用
// //ResetAbort,否则会在catch块的结尾再次引发它。ResetAbod可以取消Abort的请求,并
// //阻止ThreadAbortException终止此线程。但是,线程不一定会立即中止,或者根本不中止。
// //如果线程在作为中止过程的一部分被调用的finally块中做非常大量的计算,从而无限期延
// //迟中止操作,则会发生这种情况。若要确保线程已经终止,请在调用Abort之后对线程调
// //用Join方法。
// v.Thread.Join();
// dict.Remove(key);
//}
#endregion
WorkerThread v = FindSpecificWorkerThreadByKey(key);
//没有发现指定key的线程表示,对应该key的任务已经执行完了,不需要再来取消该任务
//或者指的key的线程虽然还在但它的状态已变为suspended,任务已完成,将等待下一个任务,实际不需要终止该线程
//只有但指定的key的任务在执行时才删除
//if (v != null && v.Thread.ThreadState != ThreadState.Suspended)
if (v != null && v.CurrentThreadState == WorkerThreadState.Busy)
{
dict.Remove(key);
/*
在调用Abort方法时,在指定线程上引发ThreadAbortException。以开始终止此线程的
过程。ThreadAbortException是—个可以由应用程序代码捕获的特殊异常,但除非调用
ResetAbort,否则会在catch块的结尾再次引发它。ResetAbod可以取消Abort的请求,并
阻止ThreadAbortException终止此线程。但是,线程不一定会立即中止,或者根本不中止。
如果线程在作为中止过程的一部分被调用的finally块中做非常大量的计算,从而无限期延
迟中止操作,则会发生这种情况。若要确保线程已经终止,请在调用Abort之后对线程调
用Join方法。
*/
v.Thread.Abort();
v.Thread.Join();
Debug.WriteLine("销毁正在执行Key="+key+"的任务的线程");
if (v.ErrorCallback != null)
{
v.ErrorCallback(v.State);
//最后完成任务的时间
v.EndExecTime = DateTime.Now;
}
}
//}
//wait.Set();
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, string key, SuccCallback succ, ErrCallback err)
{
WorkerThread p = new WorkerThread()
{
WaitCallback = callback,
State = state,
Key = key,
ErrorCallback = err,
SuccessCallback = succ
};
//queue.Enqueue(p);
lock (queue)
{
queue.Add(p);
//Monitor.Pulse(queue);
}
wait.Set();
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, SuccCallback succ, ErrCallback err)
{
QueueUserWorkItem(callback, state, System.Guid.NewGuid().ToString(), succ, err);
}
public void QueueUserWorkItem(WaitCallback2 callback, object state, string key)
{
//WorkerThread p = new WorkerThread()
// {
// WaitCallback = callback,
// State = state,
// Key = key
// };
////queue.Enqueue(p);
//queue.Add(p);
//wait.Set();
QueueUserWorkItem(callback, state, key, null, null);
}
public void QueueUserWorkItem(WaitCallback2 callback, object state)
{
QueueUserWorkItem(callback, state, System.Guid.NewGuid().ToString());
}
}
public enum WorkerThreadState : byte
{
None = 0,
Busy = 1,
Idle = 2
}
public class WorkerThread
{
public AutoResetEvent Auto = new AutoResetEvent(false);
public static ManualResetEvent Manual = new ManualResetEvent(true);
public WorkerThreadState CurrentThreadState { get; set; }
public DateTime StartExecTime { get; set; }
public DateTime EndExecTime { get; set; }
public Thread Thread { get; set; }
public string Key { get; set; }
public WaitCallback2 WaitCallback { get; set; }
public SuccCallback SuccessCallback { get; set; }
public ErrCallback ErrorCallback { get; set; }
public Object State { get; set; }
public void Exec()
{
while (true)
{
this.CurrentThreadState = WorkerThreadState.Busy;
if (this.SuccessCallback != null)
this.SuccessCallback(this.State, this.WaitCallback(this.State));
else
this.WaitCallback(this.State);//如何将执行的结果返回,目前是通过SuccessCallback将结果作为参数返回,如果没有使用SuccessCallback将不能返回执行的结果
this.EndExecTime = DateTime.Now;
//如何将任务执行的起讫时间发给任务
this.CurrentThreadState = WorkerThreadState.Idle;
//this.Thread.Suspend();
//等待60s如果在此期间未接收到新的任务该线程就退出
if (!Auto.WaitOne(60 * 1000, false))
break;
Manual.WaitOne();
}
Debug.WriteLine("线程销毁");
}
public WorkerThre
发表评论
-
关于分层架构中的业务实体层的使用一直不太清楚,可否指点一下?
2007-03-23 09:10 671我知道业务逻辑层又可细分为三个层次,分别是业务外观层业务规则层 ... -
xml反串行化
2007-07-02 17:23 7321using System; 2using Syste ... -
WriteXmlSchema(xsdFileName)和GetXmlSchema()输出的内容的差异
2007-07-04 19:00 881利用DataSet.ReadXml载入一个xml文件,再使用G ... -
对websharp中aspect的改进(待续)
2007-11-17 14:27 692缘起 为了在我的《朗志轻量级项目管理解决方案》项目中应用 ... -
WebSharp Aspect改进(续2)
2007-11-19 21:39 700接着上次在《朗志轻量级项目管理解决方案》中对Aspec ... -
TreeView(树形控件)中常用到的属性和事件
2007-11-19 22:22 12941.TreeView(树形控件) ... -
有没有适合的的面向对象的查询语言(Object Query Language)
2007-11-28 10:15 759在我做《朗志轻量级项目管理解决方案》的过程中,我希望 ... -
问题解答集
2007-11-29 18:11 4401 如何在源代码的目录下添加一个测试文件 ... -
FckEditor自定义按钮
2007-11-29 18:35 829目录 FckEditor自定义按钮 1 目录 ... -
GhstDoc2.1.1使用手册
2007-11-29 18:39 721目录 GhstDoc2.1.1使用手册 1 ... -
Log4net使用说明
2007-11-29 18:44 785Log4net使用说明 1 修改历史纪录 ... -
MySQLHelper类使用说明
2007-11-29 18:46 1314目录 MySQLHelper类使用说明 1 目录 ... -
NDoc1.3.1使用手册
2007-11-29 18:47 764目录 NDoc1.3.1使用手册 1 目录 ... -
程序中操作Word
2007-11-29 18:52 727目录 程序中操作Word 1 目录 2 ... -
利用SMTP服务发送电子邮件
2007-11-29 18:58 1352目录 利用SMTP服务发送电子邮件 1 目录 ... -
程序中操作Excel
2007-11-29 18:59 637目录 程序中操作Excel 1 目录 ... -
访问被拒绝:“AjaxPro”的解决方案
2007-11-29 19:01 531目录 访问被拒绝:&qu ... -
sqlserver的版本号
2008-02-27 21:01 819当你安装了sqlserver 2005之后你就可以使用sqls ... -
在安装有VS2008beta2版本的机子上使用vs2005进行部署出现问题的解决方法
2008-02-27 21:13 679我知道,2008rtm发布已经很久了,不巧的是同学在我的机子上 ... -
忙话codesmith
2008-07-28 15:01 865为什么不是闲话,因为我很忙,项目中新问题是接连不断,上一篇讲到 ...
相关推荐
本项目标题为“Asynchronous-Server”,它使用了非阻塞I/O(Non-blocking I/O)和自制线程池来实现这种异步服务器模型。以下是关于这个主题的详细知识: 1. **非阻塞I/O**:非阻塞I/O是与传统的阻塞I/O相反的一种...
CLR.via.C#.(中文第3版)(自制详细书签)Part3 CLR via C#(第3版) Jeffrey Richter 著 周靖 译 出版时间:2010年09月 页数:800 介绍 享有全球盛誉的编程专家Jeffrey Richter,这位与Microsoft .NET开发团队合作...
CLR.via.C#.(中文第3版)(自制详细书签)Part2 CLR via C#(第3版) Jeffrey Richter 著 周靖 译 出版时间:2010年09月 页数:800 介绍 享有全球盛誉的编程专家Jeffrey Richter,这位与Microsoft .NET开发团队...
开发者可能需要使用到线程池来并发处理多个搜索请求,提高响应速度,同时也要处理好异常情况,保证程序的稳定运行。 在实际使用中,XiLinJieSearch这个名字可能代表了该搜索器的特定版本或作者的标识。用户在使用时...
CLR.via.C#.(中文第3版)(自制详细书签) CLR via C#(第3版) Jeffrey Richter 著 周靖 译 出版时间:2010年09月 页数:800 介绍 享有全球盛誉的编程专家Jeffrey Richter,这位与Microsoft .NET开发团队合作长达...
CLR.via.C#.(中文第3版)(自制详细书签)Part2 CLR via C#(第3版) Jeffrey Richter 著 周靖 译 出版时间:2010年09月 页数:800 介绍 享有全球盛誉的编程专家Jeffrey Richter,这位与Microsoft .NET开发团队合作...
3. **设计模式**:在这些源代码中,开发者可能会发现各种设计模式的应用,如工厂模式、单例模式、观察者模式、装饰器模式等,这些都是软件工程中提高代码复用性和灵活性的重要工具。 4. **框架应用**:如果源代码...
根据提供的信息,“Java核心技术,卷1(原书第8版).pdf 中文 自制完整书签”这份资料主要聚焦于Java编程语言的核心概念和技术。由于实际内容并未给出,以下将根据该书可能涵盖的主要章节来推测其核心知识点,并对这些...
`BSerialComs`可能采用了线程池或者事件循环模型来处理串口事件,保证了主线程的流畅运行,避免了因为串口操作阻塞而影响用户体验。此外,多线程还能让程序在等待串口响应时执行其他任务,提高整体效率。 事件驱动...
2. **多线程与并发处理**:为了处理多个用户连接和消息同步,程序需要支持多线程和并发操作,这可能涉及到线程池、锁机制、异步编程模型等概念。 3. **数据库管理**:用户信息、聊天记录等数据通常存储在数据库中,...
【Java咖啡厅系统】是一款基于Java技术开发的自制咖啡厅管理系统,旨在提高咖啡厅的运营效率和服务质量。这个系统集成了订单管理、库存控制、客户关系管理、员工调度等多种功能,为小型咖啡厅提供了一站式的后台解决...
实例132 执行任务(线程池) 378 实例133 碰撞的球(多线程) 382 实例134 钟表(多线程) 387 实例135 模拟生产者与消费者 392 实例136 仿迅雷下载文件 396 第15章 图形编程 403 实例137 多变的按钮 403 ...
1.2 搭建Java所需环境 3 1.2.1 下载JDK 3 1.2.2 安装JDK 4 1.2.3 配置环境 5 1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 ...
实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的...
1.2 搭建Java所需环境 3 1.2.1 下载JDK 3 1.2.2 安装JDK 4 1.2.3 配置环境 5 1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) ...
实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的...
3.3.2线程池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 63 3.3.3推荐模式. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 64 3.4进程间通信只用TCP . . . . . . . . . . ....
实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 ...