原文来自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个。