65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.07/5 (10投票s)

2008年11月20日

CPOL

2分钟阅读

viewsIcon

72278

downloadIcon

905

本文描述了使用 .NET Framework 和 C# 3.0 实现的自定义线程池。

引言

.NET Framework BCL 包含一个非常好的线程池实现(System.Threading.ThreadPool 类)。

但是,这个类不适用于以下场景:

  1. 长时间运行的操作。通常,对于长时间运行的操作,建议使用 Thread 类。
  2. ThreadPool 是进程级别的。这意味着在 ThreadPool 中没有可用线程的情况可能会经常发生。如果你有一个非常重要且紧急的工作项,并且不想承担这种风险怎么办?但通常,尤其是在你有一个包含多个应用程序域(如 IIS 或 SQL Server)的应用程序时,你可能会耗尽线程池中的线程...
  3. ThreadPool 不支持 IAsyncResult。所有委托的 BeginInvoke 方法都会在内部将控制权传递给 ThreadPool,但 ThreadPool 本身不支持 IAsyncResult

通常,关于何时使用 ThreadPool 以及何时直接使用 Thread 类或 MulticastDelegate.BeginInvoke 有许多严格的建议。System.Threading.ThreadPool 的主要问题是它是进程级别的。因此,如果你有一组非常重要的任务要做,并且还托管了一组第三方程序集,则总是存在你的重要任务会被延迟的可能性。在 CustomThreadPool 的情况下,你为每个应用程序域都有一个单独的线程池。

你可以拥有与应用程序域数量相同的 CustomThreadPool

这只是 CustomThreadPool 的初始版本,我计划在未来扩展它。也许,我会使用 Monitor.WaitMonitor.Pulse 代替 WaitHandle,以实现更好的灵活性(可能还有性能)。

Using the Code

CustomThreadPool 有三种方法:QueueUserWorkItemQueueUserWorkItemResult<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 添加了释放功能。类从静态更改为“可实例化”,以支持在同一个应用程序域内创建多个实例。
© . All rights reserved.