野生程序员对.NETFramework 4.0 ThreadPool的理解

ThreadPool 类

提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。

命名空间:   System.Threading
程序集:  mscorlib(位于 mscorlib.dll)

版本信息


.NET Framework
自 1.1 起可用
可移植类库
可移植 .NET 平台 中受支持
Silverlight
自 2.0 起可用
Windows Phone Silverlight
自 7.0 起可用

线程安全


This type is thread safe.

一边说着要用技术安身立命,一边感叹自己的野生属性。好吧,知之为知之,不知就不知。我"以为"是这样这样那样那样,这样说真是没意思。现在的疑惑有以下几点:

  • 1、线程池内部有几个工作线程?
  • 2、使用线程池的正确姿势(场景和控制)?
  • 3、有必要自己封装一个不?

开始看MSDN文档

[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true,
	ExternalThreading = true)]
public static class ThreadPool

方法


  名称 说明
BindHandle(IntPtr)

已过时。 将操作系统句柄绑定到 ThreadPool。

BindHandle(SafeHandle)

将操作系统句柄绑定到 ThreadPool。

GetAvailableThreads(Int32, Int32)

检索由 GetMaxThreads 方法返回的最大线程池线程数和当前活动线程数之间的差值。

GetMaxThreads(Int32, Int32)

检索可以同时处于活动状态的线程池请求的数目。 所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。

GetMinThreads(Int32, Int32)

发出新的请求时,在切换到管理线程创建和销毁的算法之前检索线程池按需创建的线程的最小数量。

QueueUserWorkItem(WaitCallback)

将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。

QueueUserWorkItem(WaitCallback, Object)

将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

注册一个等待 WaitHandle 的委托,并指定一个 32 位有符号整数来表示超时值(以毫秒为单位)。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

注册一个等待 WaitHandle 的委托,并指定一个 64 位有符号整数来表示超时值(以毫秒为单位)。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

注册一个等待 WaitHandle 的委托,并指定一个 TimeSpan 值来表示超时时间。

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

指定表示超时(以毫秒为单位)的 32 位无符号整数,注册一个委托等待 WaitHandle

SetMaxThreads(Int32, Int32)

设置可以同时处于活动状态的线程池的请求数目。 所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。

SetMinThreads(Int32, Int32)

发出新的请求时,在切换到管理线程创建和销毁的算法之前设置线程池按需创建的线程的最小数量。

UnsafeQueueNativeOverlapped(NativeOverlapped*)

将重叠的 I/O 操作排队以便执行。

UnsafeQueueUserWorkItem(WaitCallback, Object)

将指定的委托排队到线程池,但不会将调用堆栈传播到辅助线程。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

注册一个等待 WaitHandle 的委托,并使用一个 32 位带符号整数来表示超时时间(以毫秒为单位)。 此方法不将调用堆栈传播到辅助线程。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

注册一个等待 WaitHandle 的委托,并指定一个 64 位有符号整数来表示超时值(以毫秒为单位)。 此方法不将调用堆栈传播到辅助线程。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

注册一个等待 WaitHandle 的委托,并指定一个 TimeSpan 值来表示超时时间。 此方法不将调用堆栈传播到辅助线程。

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

指定表示超时(以毫秒为单位)的 32 位无符号整数,注册一个委托等待 WaitHandle。 此方法不将调用堆栈传播到辅助线程。

伪代码

#region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll
#endregion

using System.Runtime.InteropServices;
using System.Security;

namespace System.Threading
{
    //
    // 摘要:
    //     提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。
    public static class ThreadPool
    {
        //
        // 摘要:
        //     将操作系统句柄绑定到 System.Threading.ThreadPool。
        //
        // 参数:
        //   osHandle:
        //     保存操作系统句柄的 System.Runtime.InteropServices.SafeHandle。在非托管端必须为重叠 I/O 打开该句柄。
        //
        // 返回结果:
        //     如果绑定了句柄,则为 true;否则为 false。
        //
        // 异常:
        //   T:System.ArgumentNullException:
        //     osHandle 为 null。
        [SecuritySafeCritical]
        public static bool BindHandle(SafeHandle osHandle);
        //
        // 摘要:
        //     将操作系统句柄绑定到 System.Threading.ThreadPool。
        //
        // 参数:
        //   osHandle:
        //     持有句柄的 System.IntPtr。在非托管端必须为重叠 I/O 打开该句柄。
        //
        // 返回结果:
        //     如果绑定了句柄,则为 true;否则为 false。
        //
        // 异常:
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [Obsolete("ThreadPool.BindHandle(IntPtr) has been deprecated.  Please use ThreadPool.BindHandle(SafeHandle) instead.", false)]
        [SecuritySafeCritical]
        public static bool BindHandle(IntPtr osHandle);
        //
        // 摘要:
        //     检索由 System.Threading.ThreadPool.GetMaxThreads([email protected],[email protected]) 方法返回的最大线程池线程数和当前活动线程数之间的差值。
        //
        // 参数:
        //   workerThreads:
        //     可用辅助线程的数目。
        //
        //   completionPortThreads:
        //     可用异步 I/O 线程的数目。
        [SecuritySafeCritical]
        public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads);
        //
        // 摘要:
        //     检索可以同时处于活动状态的线程池请求的数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
        //
        // 参数:
        //   workerThreads:
        //     线程池中辅助线程的最大数目。
        //
        //   completionPortThreads:
        //     线程池中异步 I/O 线程的最大数目。
        [SecuritySafeCritical]
        public static void GetMaxThreads(out int workerThreads, out int completionPortThreads);
        //
        // 摘要:
        //     检索线程池在新请求预测中维护的空闲线程数。
        //
        // 参数:
        //   workerThreads:
        //     当前由线程池维护的空闲辅助线程的最小数目。
        //
        //   completionPortThreads:
        //     当前由线程池维护的空闲异步 I/O 线程的最小数目。
        [SecuritySafeCritical]
        public static void GetMinThreads(out int workerThreads, out int completionPortThreads);
        //
        // 摘要:
        //     将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
        //
        // 参数:
        //   callBack:
        //     一个 System.Threading.WaitCallback,表示要执行的方法。
        //
        // 返回结果:
        //     如果此方法成功排队,则为 true;如果未能将该工作项排队,则引发 System.NotSupportedException。
        //
        // 异常:
        //   T:System.ArgumentNullException:
        //     callBack 为 null。
        //
        //   T:System.NotSupportedException:
        //     承载公共语言运行时 (CLR) 的宿主不支持此操作。
        [SecuritySafeCritical]
        public static bool QueueUserWorkItem(WaitCallback callBack);
        //
        // 摘要:
        //     将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。
        //
        // 参数:
        //   callBack:
        //     System.Threading.WaitCallback,它表示要执行的方法。
        //
        //   state:
        //     包含方法所用数据的对象。
        //
        // 返回结果:
        //     如果此方法成功排队,则为 true;如果未能将该工作项排队,则引发 System.NotSupportedException。
        //
        // 异常:
        //   T:System.NotSupportedException:
        //     承载公共语言运行时 (CLR) 的宿主不支持此操作。
        //
        //   T:System.ArgumentNullException:
        //     callBack 为 null。
        [SecuritySafeCritical]
        public static bool QueueUserWorkItem(WaitCallback callBack, object state);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并指定一个 System.TimeSpan 值来表示超时时间。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的 System.Threading.WaitOrTimerCallback 委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   timeout:
        //     System.TimeSpan 表示的超时时间。如果 timeout 为 0(零),则函数将测试对象的状态并立即返回。如果 timeout 为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     封装本机句柄的 System.Threading.RegisteredWaitHandle。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     timeout 参数小于 -1。
        //
        //   T:System.NotSupportedException:
        //     timeout 参数大于 System.Int32.MaxValue。
        [SecuritySafeCritical]
        public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, TimeSpan timeout, bool executeOnlyOnce);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并指定一个 64 位有符号整数来表示超时值(以毫秒为单位)。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的 System.Threading.WaitOrTimerCallback 委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     封装本机句柄的 System.Threading.RegisteredWaitHandle。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     millisecondsTimeOutInterval 参数小于 -1。
        [SecuritySafeCritical]
        public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并指定一个 32 位有符号整数来表示超时值(以毫秒为单位)。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的 System.Threading.WaitOrTimerCallback 委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     封装本机句柄的 System.Threading.RegisteredWaitHandle。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     millisecondsTimeOutInterval 参数小于 -1。
        [SecuritySafeCritical]
        public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce);
        //
        // 摘要:
        //     指定表示超时(以毫秒为单位)的 32 位无符号整数,注册一个委托等待 System.Threading.WaitHandle。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的 System.Threading.WaitOrTimerCallback 委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     System.Threading.RegisteredWaitHandle,可用于取消已注册的等待操作。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     millisecondsTimeOutInterval 参数小于 -1。
        [CLSCompliant(false)]
        [SecuritySafeCritical]
        public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce);
        //
        // 摘要:
        //     设置可以同时处于活动状态的线程池的请求数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
        //
        // 参数:
        //   workerThreads:
        //     线程池中辅助线程的最大数目。
        //
        //   completionPortThreads:
        //     线程池中异步 I/O 线程的最大数目。
        //
        // 返回结果:
        //     如果更改成功,则为 true;否则为 false。
        [SecuritySafeCritical]
        public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
        //
        // 摘要:
        //     设置线程池在新请求预测中维护的空闲线程数。
        //
        // 参数:
        //   workerThreads:
        //     要由线程池维护的新的最小空闲辅助线程数。
        //
        //   completionPortThreads:
        //     要由线程池维护的新的最小空闲异步 I/O 线程数。
        //
        // 返回结果:
        //     如果更改成功,则为 true;否则为 false。
        [SecuritySafeCritical]
        public static bool SetMinThreads(int workerThreads, int completionPortThreads);
        //
        // 摘要:
        //     将重叠的 I/O 操作排队以便执行。
        //
        // 参数:
        //   overlapped:
        //     要排队的 System.Threading.NativeOverlapped 结构。
        //
        // 返回结果:
        //     如果成功地将此操作排队到 I/O 完成端口,则为 true;否则为 false。
        [CLSCompliant(false)]
        [SecurityCritical]
        public static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped);
        //
        // 摘要:
        //     将指定的委托排队到线程池,但不会将调用堆栈传播到辅助线程。
        //
        // 参数:
        //   callBack:
        //     一个 System.Threading.WaitCallback,表示当线程池中的线程选择工作项时调用的委托。
        //
        //   state:
        //     在接受线程池服务时传递给委托的对象。
        //
        // 返回结果:
        //     如果方法成功,则为 true;如果未能将该工作项排队,则引发 System.OutOfMemoryException。
        //
        // 异常:
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        //
        //   T:System.ApplicationException:
        //     遇到了内存不足的情况。
        //
        //   T:System.OutOfMemoryException:
        //     未能将该工作项排队。
        //
        //   T:System.ArgumentNullException:
        //     callBack 为 null。
        [SecurityCritical]
        public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, object state);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并指定一个 64 位有符号整数来表示超时值(以毫秒为单位)。不将调用堆栈传播到辅助线程。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     System.Threading.RegisteredWaitHandle 对象,可用于取消已注册的等待操作。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     millisecondsTimeOutInterval 参数小于 -1。
        //
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [SecurityCritical]
        public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce);
        //
        // 摘要:
        //     指定表示超时(以毫秒为单位)的 32 位无符号整数,注册一个委托等待 System.Threading.WaitHandle。不将调用堆栈传播到辅助线程。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     System.Threading.RegisteredWaitHandle 对象,可用于取消已注册的等待操作。
        //
        // 异常:
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [CLSCompliant(false)]
        [SecurityCritical]
        public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并指定一个 System.TimeSpan 值来表示超时时间。不将调用堆栈传播到辅助线程。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   timeout:
        //     System.TimeSpan 表示的超时时间。如果 timeout 为 0(零),则函数将测试对象的状态并立即返回。如果 timeout 为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     System.Threading.RegisteredWaitHandle 对象,可用于取消已注册的等待操作。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     timeout 参数小于 -1。
        //
        //   T:System.NotSupportedException:
        //     timeout 参数大于 System.Int32.MaxValue。
        //
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [SecurityCritical]
        public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, TimeSpan timeout, bool executeOnlyOnce);
        //
        // 摘要:
        //     注册一个等待 System.Threading.WaitHandle 的委托,并使用一个 32 位带符号整数来表示超时时间(以毫秒为单位)。不将调用堆栈传播到辅助线程。
        //
        // 参数:
        //   waitObject:
        //     要注册的 System.Threading.WaitHandle。使用 System.Threading.WaitHandle 而非 System.Threading.Mutex。
        //
        //   callBack:
        //     waitObject 参数终止时调用的委托。
        //
        //   state:
        //     传递给委托的对象。
        //
        //   millisecondsTimeOutInterval:
        //     以毫秒为单位的超时。如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。如果 millisecondsTimeOutInterval
        //     为 -1,则函数的超时间隔永远不过期。
        //
        //   executeOnlyOnce:
        //     如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
        //
        // 返回结果:
        //     System.Threading.RegisteredWaitHandle 对象,可用于取消已注册的等待操作。
        //
        // 异常:
        //   T:System.ArgumentOutOfRangeException:
        //     millisecondsTimeOutInterval 参数小于 -1。
        //
        //   T:System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [SecurityCritical]
        public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce);
    }
}

  “承载公共语言运行时 (CLR) 的宿主不支持此操作”出现了好多次吧。试试反编译mscorlib.dll,看看有什么发现。

	[SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern bool AdjustThreadsInPool(uint QueueLength);
		[CLSCompliant(false), SecurityCritical]
		public unsafe static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped)
		{
		}
		[SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern bool ShouldUseNewWorkerPool();
		[SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern bool CompleteThreadPoolRequest(uint QueueLength);
		[SecurityCritical]
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern bool NotifyWorkItemComplete();
		[SecurityCritical]
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void ReportThreadStatus(bool isWorking);
		[SecuritySafeCritical]
		internal static void NotifyWorkItemProgress()
		{
		}
		[SecurityCritical]
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void NotifyWorkItemProgressNative();
		[SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern bool ShouldReturnToVm();
		[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern bool SetAppDomainRequestActive();
		[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SecurityCritical, SuppressUnmanagedCodeSecurity]
		[DllImport("QCall", CharSet = CharSet.Unicode)]
		internal static extern void ClearAppDomainRequestActive();
		[SecurityCritical]
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern bool IsThreadPoolHosted();
		[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SecurityCritical]
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void SetNativeTpEvent();

  

[MethodImplAttribute(MethodImplOptions.Synchronized)]标签应用到实例方法,相当于对当前实例加锁 lock(this)

[MethodImplAttribute(MethodImplOptions.Synchronized)]标签应用到静态方法,相当于当前类型加锁。如 WithDraw 是静态方法,就相当于 lock (typeof(Account))

接下来我们再来看看SynchronizationAttribute类:

MSDN对SynchronizationAttribute的解释为:为当前上下文和所有共享同一实例的上下文强制一个同步域。
SynchronizationAttribute 的类:一个在 System.Runtime.Remoting.Contexts 命名空间中,另一个在 System.EnterpriseServices 命名空间中。System.EnterpriseServices.SynchronizationAttribute 类仅支持同步调用,并且只可与接受服务的组件一起使用。System.Runtime.Remoting.Contexts.SynchronizationAttribute 同时支持同步调用和异步调用,并且只可与上下文绑定对象一起使用。

毛发现都没有,看来还是功力尚浅,资质平庸啊。发现了一堆空方法,什么鬼?都是没有具体实现的。看来先猜上一猜了:SetMaxThreads和SetMinThreads说明可以设置工作线程的数量,线程的内部使用了完成端口(没文化的我理解为ConcurrentQueue,大白话就是说是一个线程安全的队列)。那么完成端口编程模式号称是windows系统最优秀的编程模型,会不会非常智能呢?是不是不调用SetMaxThreads和SetMinThreads操作系统就根据你机器的CPU核心数来自己设定最大值呢?

回到前面的几个问题,偶还是搞不清楚啊。谁能告诉我,什么是什么,什么是什么...咦,这兄台唱上了吧。^_^

反编译大神实现的CoreThreadPool

public class CoreThreadPool : IDisposable
    {
        /// <summary>
        /// 队列元素申明
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        private class PoolData
        {
            /// <summary>
            /// 外部要求放入队列的数据
            /// </summary>
            public object Data;
            /// <summary>
            /// 需要执行的命令(Exit/Command(自定义))
            /// </summary>
            public CoreThreadPool.PoolCommand Command;
            public PoolData()
            {
                this.Command = CoreThreadPool.PoolCommand.Exit;
            }
            public PoolData(object data)
            {
                this.Data = data;
                this.Command = CoreThreadPool.PoolCommand.Command;
            }
            public PoolData(CoreThreadPool.PoolCommand cmd)
            {
                this.Command = cmd;
            }
        }
        protected enum PoolCommand
        {
            Command,
            Exit
        }
        protected SafeFileHandle complatePort;
        /// <summary>
        /// 线程池主线程
        /// </summary>
        protected Thread thread;
        protected volatile bool isOpened;
        [method: CompilerGenerated]
        [CompilerGenerated]
        public event Action<object> Exceute;
        [method: CompilerGenerated]
        [CompilerGenerated]
        public event Action<object> ExitExceute;
        /// <summary>
        /// 线程池是否正在运行
        /// </summary>
        public bool IsOpened
        {
            get
            {
                return this.isOpened;
            }
            set
            {
                this.isOpened = value;
            }
        }
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern SafeFileHandle CreateIoCompletionPort(IntPtr FileHandle, IntPtr ExistingCompletionPort, IntPtr CompletionKey, uint NumberOfConcurrentThreads);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool GetQueuedCompletionStatus(SafeFileHandle CompletionPort, out uint lpNumberOfBytesTransferred, out IntPtr lpCompletionKey, out IntPtr lpOverlapped, uint dwMilliseconds);
        [DllImport("Kernel32", CharSet = CharSet.Auto)]
        private static extern bool PostQueuedCompletionStatus(SafeFileHandle CompletionPort, uint dwNumberOfBytesTransferred, IntPtr dwCompletionKey, IntPtr lpOverlapped);
        /// <summary>
        /// 启动线程池的主线程
        /// </summary>
        public void Start()
        {
            isOpened = true;
            if (thread != null)
            {
                throw new Exception("线程池已经是启动状态!");
            }
            complatePort = CreateIoCompletionPort(new IntPtr(-1), IntPtr.Zero, IntPtr.Zero, 0u);
            if (complatePort.IsInvalid)
            {
                throw new Exception(string.Format("创建IOCP出错!原因是:{0}", Marshal.GetLastWin32Error().ToString()));
            }
            thread = new Thread(new ParameterizedThreadStart(this.Run));
            thread.Start(complatePort);
        }
        /// <summary>
        /// 外部提交数据对象到队列
        /// </summary>
        /// <param name="data"></param>
        public void Post(object data)
        {
            PostData(new CoreThreadPool.PoolData(data));
        }
        /// <summary>
        /// 线程池主线程执行逻辑
        /// </summary>
        /// <param name="CompletionPortID"></param>
        private void Run(object CompletionPortID)
        {
            SafeFileHandle completionPort = (SafeFileHandle)CompletionPortID;
            while (IsOpened)
            {
                uint num;
                IntPtr intPtr;
                IntPtr value;
                //从队列里取出最前面的对象
                CoreThreadPool.GetQueuedCompletionStatus(completionPort, out num, out intPtr, out value, 4294967295u);
                if (num > 0u)
                {
                    GCHandle gCHandle = GCHandle.FromIntPtr(value);
                    CoreThreadPool.PoolData poolData = (CoreThreadPool.PoolData)gCHandle.Target;
                    gCHandle.Free();
                    if (poolData.Command != CoreThreadPool.PoolCommand.Command)
                    {
                        IsOpened = false;
                        break;
                    }
                    RaiseExecute(poolData.Data);
                }
            }
            RaiseExitExecute("线程池已经停止。");
            isOpened = false;
            thread = null;
        }
        /// <summary>
        /// 触发Execute事件
        /// </summary>
        /// <param name="data"></param>
        private void RaiseExecute(object data)
        {
            Exceute?.Invoke(data);
        }
        /// <summary>
        /// 触发ExitExecute事件
        /// </summary>
        /// <param name="data"></param>
        private void RaiseExitExecute(object data)
        {
            ExitExceute?.Invoke(data);
        }
        /// <summary>
        /// 结束线程池主线程
        /// </summary>
        public void Stop()
        {
            PostData(new PoolData(PoolCommand.Exit));
            IsOpened = false;
        }
        /// <summary>
        /// 内部提交数据到线程池队列中
        /// </summary>
        /// <param name="data"></param>
        private void PostData(PoolData data)
        {
            if (complatePort.IsClosed)
            {
                return;
            }
            GCHandle value = GCHandle.Alloc(data);
            PostQueuedCompletionStatus(complatePort, (uint)IntPtr.Size, IntPtr.Zero, GCHandle.ToIntPtr(value));
        }
        public void Dispose()
        {
            if (this.thread != null && this.thread.ThreadState != System.Threading.ThreadState.Stopped)
            {
                this.Stop();
            }
        }
    }

  

时间: 2024-10-25 17:05:20

野生程序员对.NETFramework 4.0 ThreadPool的理解的相关文章

程序员修炼之路-(0)目录

前言:<程序员修炼之路-(0)前言:在路上, 再上路> 在前言中已经对知识体系进行了梳理,主要分为问题定义.算法与数据结构.系统平台API.编程语言实现.代码设计.测试验证等等.目前集中精力编写算法与数据结构部分,这可能也是最艰难的一部分,之后再考虑补充其他部分. 对于这一部分的内容编排,主要以<算法设计与分析基础>.<算法>以及LeetCode算法题中的问题分类为横向,以<算法设计与分析基础>中罗列的经典设计技巧为纵向,贯穿每一小节.因为传统算法书籍的结构

野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人(转)

本文摘自:<Web 全栈工程师的自我修养> 野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人.野生程序员有很强大的单兵作战能力,但是在编入“正规军”之后,可能会不适应新的做事方法. 遭遇“野生程序员” 腾讯公司内部的团队很多,在团队管理上有项目和专业两个维度.也就是说,有些团队是项目维度的,整个团队共同维护一个产品,成员来自不同的职业岗位:有些团队是专业维度的,比如一个组都是前端工程师,维护不同的产品. 因为前端组是设计部最接近后台技术的团队,所

野生程序员的故事

本文摘自:<Web 全栈工程师的自我修养> 摘自:http://kb.cnblogs.com/page/528495/ 野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人.野生程序员有很强大的单兵作战能力,但是在编入“正规军”之后,可能会不适应新的做事方法. 遭遇“野生程序员” 腾讯公司内部的团队很多,在团队管理上有项目和专业两个维度.也就是说,有些团队是项目维度的,整个团队共同维护一个产品,成员来自不同的职业岗位:有些团队是专业维度的,比如一个组

野生程序员眼中的Linux系统

            我是一名后端开发者,从一个啥都不知道的小白,跨专业自学了PHP,江湖人称--野生程序员,所幸也算勉强混的一口饭吃.众所周知,计算机专业和非计算机专业其实是有很大的区别,计算机专业的课程大多是底层的原理,而我这个门外汉对此一窍不通,我投机取巧,在前辈们造好的轮子上开发.由此,对于Linux,我可谓是小白一个,我不懂计算机原理,不懂数据结构,自然对Linux的许多概念不理解.直到现在,我对Linux的底层架构还是懵懵懂懂.下面我想谈谈这两年来我眼中的Linux. 我的第一份工

野生程序员的故事,不错,看后有一些感悟

本文摘自:<Web 全栈工程师的自我修养> 野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人.野生程序员有很强大的单兵作战能力,但是在编入“正规军”之后,可能会不适应新的做事方法. 遭遇“野生程序员” 腾讯公司内部的团队很多,在团队管理上有项目和专业两个维度.也就是说,有些团队是项目维度的,整个团队共同维护一个产品,成员来自不同的职业岗位:有些团队是专业维度的,比如一个组都是前端工程师,维护不同的产品. 因为前端组是设计部最接近后台技术的团队,所

野生程序员的自我修养

你知道吗,一年只有8760个小时. 只注重实现效果,却没考虑这样实现的原理是什么,后来找工作吃了很大的亏,当面试官问一些功能实现的原理是什么时,我不知道怎么回答,导致最后被几家公司拒绝了.所以深有体会野生程序员,这样的人看似什么都知道一点,但实际上都只是皮毛.所以我也特别想告诉那些刚学编程的同学,一定要先选好领域,然后在这一领域磨练,把本质吃透,在追求结果的同时一定要知道过程是怎么实现的,因为有时候技术是相通的,学会了这个技术的原理,再学习其他相关的技术就比较容易了.等对一个领域了解比较透彻后,

野生程序员初长成——记北大程序设计与算法专项课程

欢迎转载,博客中的文章均为meelo原创,转载请务必以链接形式注明本文地址:www.cnblogs.com/meelo/p/5595306.html <程序设计与算法>是北京大学在Coursera上开设的一个专项课程.专项课程由6门课程构成,分别是计算导论.C程序设计.C++程序设计.算法基础.数据结构基础.高级数据结构与算法,外加一个编程毕业项目.专项课程没有假定任何先修知识,如果你对编程感兴趣或者羡慕程序员的高工资,你都可以学习这个专项课程来感悟编程的滋味.教授这些课程的老师都是北大的教授

程序员的Epic Fail [0]

作为程序员,我们经常会被客户问的一个问题一定是不是说很容易么,为什么花了这么长时间.不得不说,程序员可能是最糟糕的计划者,按时按点按计划完成的软件项目永远是下一个项目.一个项目的延期,有很多这样那样的原因,其中不得不说的一个原因就是很多代码想起来很容易,但是真的写起来,细节里全是魔鬼.在这个Epic Fail的系列中,我会记录一些在我平常写代码的过程中遇到的那些本来很简单却花了很长时间的有趣问题.这个系列会不定时更新,不断记录我写代码中的糗事,希望我永远不用更新:). 作为开篇,记录一个花了我1

野生程序员初长成 记北大程序设计与算法专项课程

<程序设计与算法>是北京大学在Coursera上开设的一个专项课程.专项课程由6门课程构成,分别是计算导论.C程序设计.C++程序设计.算法基础.数据结构基础.高级数据结构与算法,外加一个编程毕业项目.专项课程没有假定任何先修知识,如果你对编程感兴趣或者羡慕程序员的高工资,你都可以学习这个专项课程来感悟编程的滋味.教授这些课程的老师都是北大的教授,所以课程的内容是毋庸置疑的.下面是教授专项课程的四位老师. 这6门课程,每门课程大致有6周的课程内容,真实对应于北大开设的三门课.所以不用说,这个专