使用 C# 实现的自定义线程池






2.07/5 (10投票s)
本文描述了使用 .NET Framework 和 C# 3.0 实现的自定义线程池。
引言
.NET Framework BCL 包含一个非常好的线程池实现(System.Threading.ThreadPool
类)。
但是,这个类不适用于以下场景:
- 长时间运行的操作。通常,对于长时间运行的操作,建议使用
Thread
类。 ThreadPool
是进程级别的。这意味着在ThreadPool
中没有可用线程的情况可能会经常发生。如果你有一个非常重要且紧急的工作项,并且不想承担这种风险怎么办?但通常,尤其是在你有一个包含多个应用程序域(如 IIS 或 SQL Server)的应用程序时,你可能会耗尽线程池中的线程...ThreadPool
不支持IAsyncResult
。所有委托的BeginInvoke
方法都会在内部将控制权传递给ThreadPool
,但ThreadPool
本身不支持IAsyncResult
。
通常,关于何时使用 ThreadPool
以及何时直接使用 Thread
类或 MulticastDelegate.BeginInvoke
有许多严格的建议。System.Threading.ThreadPool
的主要问题是它是进程级别的。因此,如果你有一组非常重要的任务要做,并且还托管了一组第三方程序集,则总是存在你的重要任务会被延迟的可能性。在 CustomThreadPool
的情况下,你为每个应用程序域都有一个单独的线程池。
你可以拥有与应用程序域数量相同的 CustomThreadPool
。
这只是 CustomThreadPool
的初始版本,我计划在未来扩展它。也许,我会使用 Monitor.Wait
和 Monitor.Pulse
代替 WaitHandle
,以实现更好的灵活性(可能还有性能)。
Using the Code
CustomThreadPool
有三种方法:QueueUserWorkItem
、QueueUserWorkItemResult<tresult>
和 RetreiveUserWorkItemResult
。
下面提供了一个如何使用这些方法的示例:
public static class Program
{
//main entry point
public static void Main()
{
//schedule of
CustomThreadPool.QueueUserWorkItem(DoSomething);
CustomThreadPool.QueueUserWorkItemResultt<int>(MyLongRunningFunc,
MyLongRunningFuncFinished);
}
//my long-running task
private static void DoSomething()
{
Console.WriteLine("Hello, world!");
}
//my long-running function
private static int MyLongRunningFunc()
{
return 888;
}
//CustomThreadPool supports IAsyncResult
private static void MyLongRunningFuncFinished(IAsyncResult result)
{
Console.WriteLine(CustomThreadPool.RetreiveUserWorkItemResult<int>(result));
}
}
关注点
我学到了很多关于多线程的知识,尤其是关于易变字段和 IAsyncResult
实现的知识。
历史
- 2008 年 11 月 20 日 -- 初始发布
- 2009 年 3 月 10 日 -- 向
CustomThreadPool
添加了释放功能。类从静态更改为“可实例化”,以支持在同一个应用程序域内创建多个实例。