NETFramework 4.0 ThreadPool的理解

来源:互联网 发布:mac键盘灯怎么开 编辑:程序博客网 时间:2024/04/28 19:35

提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 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文档

1
2
3
[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。 此方法不将调用堆栈传播到辅助线程。

伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#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,看看有什么发现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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();
            }
        }
    }
原创粉丝点击