需求:
有一种任务需要定时的执行,而且非常的耗时,因此我把它放到线程池中执行,并设置线程池为1,如果该任务已经在队列中或正在执行该任务,则不要再将该任务加入线程池中了。
测试代码如下
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
using
System.Threading;
6
using
ThreadPool2;
7
8
namespace
ThreadPoolTest.MyThreadPool2Test
9
{
10
class
Class6
11
{
12
static
void
Main(
string
[] args)
13
{
14
MyThreadPool2 pool
=
new
MyThreadPool2(
1
,
true
,
30000
);
15
object
obj
=
new
object
();
16
Random rnd
=
new
Random();
17
for
(var i
=
0
; i
<
20
;i
++
)
18
pool.QueueUserWorkItem(call, obj, rnd.Next(
1
,
4
).ToString(), succ, err);
19
Console.ReadLine();
20
}
21
22
private
static
void
err(
object
state)
23
{
24
Console.WriteLine(
"
err
"
);
25
}
26
27
private
static
void
succ(
object
state,
object
result)
28
{
29
Console.WriteLine(
"
succ
"
);
30
}
31
32
private
static
object
call(
object
state)
33
{
34
while
(
true
)
35
{
36
Thread.Sleep(
2000
);
37
Console.WriteLine(
"
exec
"
);
38
}
39
}
40
}
41
}
42
线程池代码如下,
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 int IdleTimeout { 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="MaxLimitedTime"> 单个任务执行的最大时间 </param> public MyThreadPool2( int num, bool b, int MaxLimitedTime) { System.Threading.ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(aa), state, 2000 , true ); if (num < 1 ) num = 1 ; MaxThreadNum = num; IsLimitedExecTime = b; this .MaxLimitedTime = MaxLimitedTime; if (IsLimitedExecTime) System.Threading.ThreadPool.RegisterWaitForSingleObject(wait2, new WaitOrTimerCallback(bb), state, this .MaxLimitedTime, true ); } /**/ /// <summary> /// 定时将队列中的数据装载到线程中执行,如果还没有到达最大线程数还有任务则创建线程 /// </summary> /// <param name="state"></param> /// <param name="timedOut"></param> private void aa( object state, bool timedOut) { // Console.WriteLine("执行aa()将队列中的任务加到线程中"); lock (WorkerThread.Manual) { WorkerThread.Manual.Reset(); lock (queue) { Console.WriteLine( " queue count={0} " ,queue.Count); // 判断任务队列中有无积压的任务且有无空闲的线程,如果符合上述条件则执行之 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)