原文来自Smart Thread Pool。
OnWIGIdleEvent:
判断Work Item组是否为Idle状态,提供OnIdle事件处理过程就行。
public class OnWIGIdleEventExample
{
public void DoWork(object [] states)
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1);
wig.OnIdle += wig_OnIdle;
int i = 0;
foreach(object state in states)
{
Console.WriteLine("Queue work item " + (i++).ToString());
wig.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), state);
}
smartThreadPool.WaitForIdle();
smartThreadPool.Shutdown();
}
private object DoSomeWork(object state)
{
// Do the work
int time = (int)state;
System.Threading.Thread.Sleep(time);
Console.WriteLine("DoSomeWork, Sleep " + time.ToString());
return null;
}
private void wig_OnIdle(IWorkItemsGroup workItemsGroup)
{
Debug.WriteLine("WIG is idle, group name= "+workItemsGroup.Name);
Console.WriteLine("WIG is idle, group name= " + workItemsGroup.Name);
}
}
程序把输入的数组参数传入到每个线程中,当整个线程组处于Idle的状态时,就触发wig_OnIdle事件。
ParallelQuickSort:
使用IWorkItemsGroup来并行的给数组排序,以加快排序速度,可惜我看不明白,暂时放弃就不贴代码了。
PriorityExample:
在线程池中指定某个线程的优先级,代码如下:
public class PriorityExample
{
public void DoWork()
{
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.StartSuspended = true;
SmartThreadPool smartThreadPool = new SmartThreadPool(stpStartInfo);
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
"Queued first",
WorkItemPriority.BelowNormal);
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
"Queued second",
WorkItemPriority.AboveNormal);
smartThreadPool.Start();
smartThreadPool.WaitForIdle();
smartThreadPool.Shutdown();
}
private object DoSomeWork(object state)
{
Console.WriteLine(state.ToString());
return null;
}
}
运行结束,虽说第一个线程先释放,由于它的优先级比较低,所以它后完成,输出:
Queued second
Queued first
此例中在开始创建线程组时,指定了开始状态为Suspended,在分配完工作后,在开始Start。这种特征同样适用于WorkItemGroup,具体实例可见SuspendedWIGStartExamples.cs。
SimpleExample:
介绍了如何使用线程池来求数组的平均值,并返回结果。
public class SimpleExample
{
public void DoWork(int[] numbers)
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
// Queue the work item
IWorkItemResult<double> wir = smartThreadPool.QueueWorkItem(new Func<int[], double>(CalcAverage), numbers);
// Do some other work here
// Get the result of the operation
double average = wir.Result;
Console.WriteLine("Average= " + average.ToString());
smartThreadPool.Shutdown();
}
// Do the real work
private double CalcAverage(int[] numbers)
{
double average = 0.0;
int sum = 0;
for (int i= 0; i < numbers.Length; i++)
sum += numbers[i];
average = sum / numbers.Length;
return average;
}
}
关键在于这句:
IWorkItemResult<double> wir = smartThreadPool.QueueWorkItem(new Func<int[], double>(CalcAverage), numbers);
指定输入输出类型,及实际的工作函数,并返回double型的结果wir。
ThreadEvents:
在实际工作中可能会需要指定工作前分配资源,工作结束时需要释放资源,这时候就需要线程池提供两个事件,即OnInitialization和OnTermination,如:
public class MyResource : IDisposable
{
// ...
public void DoIt()
{
//...
}
public void Dispose()
{
//...
}
}
public class ThreadEventsExample
{
public static void Main()
{
SmartThreadPool stp = new SmartThreadPool();
stp.OnThreadInitialization += OnInitialization;
stp.OnThreadTermination += OnTermination;
stp.QueueWorkItem(DoSomeWork);
}
[ThreadStatic]
private static MyResource _resource;
public static void OnInitialization()
{
// Initialize the resource
_resource = new MyResource();
}
private static object DoSomeWork(object state)
{
// Use the resouce
_resource.DoIt();
return null;
}
public static void OnTermination()
{
// Do resource cleanup
_resource.Dispose();
}
}
WaitAll:
如果同时需要等待多个线程的返回结果,可以使用SmartThreadPool的WaitAll来实现。这在自动控制领域不同线程等待多个不同的信号很有用,这也是我最欣赏此SmartThreadPool的地方。
public class WaitForAllExample
{
public void DoWork()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new
WorkItemCallback(this.DoSomeWork1), null);
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new
WorkItemCallback(this.DoSomeWork2), null);
bool success = SmartThreadPool.WaitAll(new IWorkItemResult [] { wir1, wir2 });
if (success)
{
int result1 = (int)wir1.Result;
int result2 = (int)wir2.Result;
}
smartThreadPool.Shutdown();
}
private object DoSomeWork1(object state)
{
return 1;
}
private object DoSomeWork2(object state)
{
return 2;
}
}
WaitAny:
等待任何一个线程结束的情况下可以使用WaitAny来实现:
public class WaitForAnyExample
{
public void DoWork()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new
WorkItemCallback(this.DoSomeWork1), null);
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new
WorkItemCallback(this.DoSomeWork2), null);
IWorkItemResult [] wirs = new IWorkItemResult [] { wir1, wir2 };
int index = SmartThreadPool.WaitAny(wirs);
if (index != WaitHandle.WaitTimeout)
{
int result = (int)wirs[index].Result;
}
smartThreadPool.Shutdown();
}
private object DoSomeWork1(object state)
{
return 1;
}
private object DoSomeWork2(object state)
{
return 1;
}
}
上面代码也展示了如何区分我们等到的线程的Index。
以上使用WaitAny,WaitAll,要求我们必须在MTA情况下;同时,注意到,Windows中对WaitAny是支持到64个handle. WaitAll更加灵活,SmartThreadPool并不受限于此,也就是说可以超过64个。