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(System.Int32@,System.Int32@) 方法返回的最大线程池线程数和当前活动线程数之间的差值。
//
// 参数:
// 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();
}
}
}

经过几个小时测试,最终得出一个结论:ThreadPool的性能已经上了天。微软威武!不用再去重复造轮子了。这个线程池的使用场景是生产线上的高速生产线的采集器上用的,毫秒级别的,但也是1秒几十个产品而已。

测试代码

 class Program
{
private static Stopwatch sw = new Stopwatch();
static void Main(string[] args)
{
int id = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("CurrentThread.ManagedThreadId是:" + id.ToString());
ThreadPool.QueueUserWorkItem(Pool_Exceute, null);
Action task = () =>
{
Thread thread = new Thread(() =>
{
while (true)
{
object queueObj;
queueObj = (object)DateTime.Now.Ticks;
sw.Reset();
sw.Start();
if (ThreadPool.QueueUserWorkItem(Pool_Exceute, queueObj))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(DateTime.Now + "->成功抛入队列,抛入的委托对象的参数是:" + queueObj.ToString());
}
Thread.Sleep(1);
}
});
thread.Start();
};
Parallel.Invoke(task, task, task, task, task);
Console.ReadLine();
} private static void Pool_Exceute(object obj)
{
if (obj != null)
{
Console.ResetColor();
int id = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("CurrentThread.ManagedThreadId是:" + id.ToString());
Console.WriteLine(DateTime.Now + "->委托对象是:" + obj.ToString());
int workThread_Count = 0;
int id_IOCP = 0;
ThreadPool.GetMaxThreads(out workThread_Count, out id_IOCP);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(DateTime.Now + string.Format("->线程池最大工作线程数是{0}.当前完成端口的ID是{1}.", workThread_Count, id_IOCP));
ThreadPool.GetAvailableThreads(out workThread_Count, out id_IOCP);
Console.WriteLine(DateTime.Now + string.Format("->线程池当前可用的工作线程数是{0}.当前完成端口的ID是{1}.", workThread_Count, id_IOCP));
sw.Stop();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("从入队到出队耗时:" + sw.ElapsedMilliseconds);
sw.Reset();
}
}
}

  

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

  1. python——创建django项目全攻略(野生程序员到家养程序员的完美进化)

    新建工程 我用pycharm写代码,所以一般就用pycharm创建django工程.右上角File-New Project.选择路径,修改项目名称,确定.就可以创建一个新的django工程.     ...

  2. 软工+C(2017第7期) 野生程序员

    // 上一篇:最近发展区/脚手架 // 下一篇:提问和回复 怎样做足够好的软件?我们就差一个程序员! 没有什么软件工程的理论的时候,程序员们凭借自己对编程的热爱,凭借着:"这是一个可以自动化 ...

  3. 软工+C(7): 野生程序员

    // 上一篇:最近发展区/脚手架 // 下一篇:提问和回复 怎样做足够好的软件?我们就差一个程序员! 没有什么软件工程的理论的时候,程序员们凭借自己对编程的热爱,凭借着:"这是一个可以自动化 ...

  4. 程序员的Epic Fail [0]

    作为程序员,我们经常会被客户问的一个问题一定是不是说很容易么,为什么花了这么长时间.不得不说,程序员可能是最糟糕的计划者,按时按点按计划完成的软件项目永远是下一个项目.一个项目的延期,有很多这样那样的 ...

  5. 顶级c程序员之路 选学篇-1 深入理解字节,字节序与字节对齐

     深入理解字节,字节序与字节对齐 一 总述 作为一个职业的coder玩家,首先应该对计算机的字节有所了解. 我们经常谈到的2进制流,字节(字符)流,数据类型流(针对编程),结构流等说法,2进制流,0和 ...

  6. 程序员的自我救赎---3.1:理解Oauth2.0

    <前言> (一) Winner2.0 框架基础分析 (二)PLSQL报表系统 (三)SSO单点登录 (四) 短信中心与消息中心 (五)钱包系统 (六)GPU支付中心 (七)权限系统 (八) ...

  7. 35岁老半路程序员的Python从0开始之路

    9年的ERP程式开发与维护,继而转向一年的售前,再到三年半的跨行业务,近4的兜兜转转又转回来做程式了,不过与之前不同的,是这次是新的程序语言Python, 同时此次是为了教学生而学习! 从今天开始,正 ...

  8. 聊聊阿里社招面试,谈谈“野生”Java程序员学习的道路

    引言 很尴尬的是,这个类型的文章其实之前笔者就写过,原文章里,笔者自称LZ(也就是楼主,有人说是老子的简写,笔者只想说,这位同学你站出来,保证不打死你,-_-),原文章名称叫做<回答阿里社招面试 ...

  9. 谈谈Java程序员进阶的那些知识和方向

    谈谈Java程序员进阶的那些知识和方向 记得前段时间看过一篇文章谈到一种程序员叫野生程序员,战斗力极强,可以搞定一切问题,但是通常看问题抓不到本质,或者说是google/baidu/stackover ...

随机推荐

  1. [leetcode-594-Longest Harmonious Subsequence]

    We define a harmonious array is an array where the difference between its maximum value and its mini ...

  2. Example002定时打开窗口

    <!--实例002定时打开窗口--> <script> // 3秒后弹出窗口: function time() { window.open("index.html&q ...

  3. PHP实现简单的评论与回复功能还有删除信息

    我们首先先看一下功能 上面黑色的是评论的下面红色的字体是回复的 再来看看怎么实现的 1.发布评论 <form action="pinglunchili.php" method ...

  4. 简单RPC框架-业务线程池

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  5. html5小游戏基础知识

    显示一个DIV和隐藏一个DIV 首先,我们要显示一个DIV和隐藏一个DIV需要使用css里面使用: .hide{ display:none;} .show{display:block;} 在需要显示或 ...

  6. java生成首字母拼音简码的总结

    百度找到了某论坛高人写的java(具体论坛记不清了),直接用来调用,再次非常感谢,基本上实现了我的需求 package MD5;import java.util.Scanner;public clas ...

  7. MinGW(GCC)编译DLL文件

    这两天用CB(Code::Blocks)写个小程序,要编译出DLL供VB(6)使用.CB使用mingw-gcc作为编译器,在库文件的产出上跟VC.VS之类的IDE略有不同. 由于C语言的基础知识不是太 ...

  8. JavaWeb 后端 <九> 之 JDBC加强

    一.大结果集的分页(重点,难点) 1.分批次查询:分页 2.基于数据库的分页:依赖的是数据库的分页语句(不同数据库是不同的) MySQL:每页显示10条. select * from XXX limi ...

  9. Luogu 1402 酒店之王(二分图最大匹配)

    Luogu 1402 酒店之王(二分图最大匹配) Description XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自 ...

  10. Jmeter连接DB2/ORACLE/MYSQL数据库

    连接DB2 1.将db2数据库驱动db2java.jar.db2jcc.jar放入jmeter的lib/下,同时也要放入本地jdk目录下例如:C:\Program Files\Java\jdk1.7. ...