对线程的进一步加深:
1 // 2 // 摘要: 3 // 将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。 4 // 5 // 参数: 6 // callBack: 7 // 一个 System.Threading.WaitCallback,表示要执行的方法。 8 // 9 // 返回结果: 10 // 如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 System.NotSupportedException。 11 // 12 // 异常: 13 // T:System.ArgumentNullException: 14 // callBack 为 null。 15 // 16 // T:System.NotSupportedException: 17 // 承载公共语言运行时 (CLR),并且主机不支持此操作。 18 [SecuritySafeCritical] 19 public static bool QueueUserWorkItem(WaitCallback callBack); 20 // 21 // 摘要: 22 // 将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。 23 // 24 // 参数: 25 // callBack: 26 // System.Threading.WaitCallback,它表示要执行的方法。 27 // 28 // state: 29 // 包含方法所用数据的对象。 30 // 31 // 返回结果: 32 // 如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 System.NotSupportedException。 33 // 34 // 异常: 35 // T:System.NotSupportedException: 36 // 承载公共语言运行时 (CLR),并且主机不支持此操作。 37 // 38 // T:System.ArgumentNullException: 39 // callBack 为 null。 40 [SecuritySafeCritical] 41 public static bool QueueUserWorkItem(WaitCallback callBack, object state);
1 #region PoolSet 2 //ThreadPool.SetMaxThreads(8, 8);//最小也是核数 3 //ThreadPool.SetMinThreads(8, 8); 4 int workerThreads = 0; 5 int ioThreads = 0; 6 ThreadPool.GetMaxThreads(out workerThreads, out ioThreads); 7 Console.WriteLine(String.Format("Max worker threads: {0}; Max I/O threads: {1}", workerThreads, ioThreads)); 8 9 ThreadPool.GetMinThreads(out workerThreads, out ioThreads); 10 Console.WriteLine(String.Format("Min worker threads: {0}; Min I/O threads: {1}", workerThreads, ioThreads)); 11 12 ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads); 13 Console.WriteLine(String.Format("Available worker threads: {0}; Available I/O threads: {1}", workerThreads, ioThreads)); 14 #endregion
1 namespace System.Threading 2 { 3 // 4 // 摘要: 5 // 通知一个或多个正在等待的线程已发生事件。 此类不能被继承。 6 [ComVisible(true)] 7 public sealed class ManualResetEvent : EventWaitHandle 8 { 9 // 10 // 摘要: 11 // 新实例初始化 System.Threading.ManualResetEvent 使用 Boolean 值,该值指示是否将初始状态设置为终止状态的类。 12 // 13 // 参数: 14 // initialState: 15 // true 若要设置的初始状态信号; false 初始状态设置为终止状态。 16 public ManualResetEvent(bool initialState); 17 } 18 }
线程池可以对多线程的调度加以管理,类似于操作系统里的知识。
1 信号量的理解
1 #region ManualResetEvent 信号量 2 { 3 ManualResetEvent mre = new ManualResetEvent(false);//false 关闭状态 4 new Action(() => 5 { 6 Thread.Sleep(5000); 7 Console.WriteLine("委托的异步调用"); 8 mre.Set();//打开状态 9 }).BeginInvoke(null, null); 10 11 mre.WaitOne();//等待打开信号量打开(申请资源) 12 Console.WriteLine("12345");//打开后执行 13 mre.Reset();//关闭(重置状态,回到初始状态)
14 new Action(() => 15 { 16 Thread.Sleep(5000); 17 Console.WriteLine("委托的异步调用2"); 18 mre.Set();//打开状态 19 }).BeginInvoke(null, null); 20 mre.WaitOne(); 21 Console.WriteLine("23456"); 22 } 23 #endregion
2 ThreadPool.QueueUserWorkItem ---将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。
1 ManualResetEvent mre = new ManualResetEvent(false);//信号量
2 ThreadPool.QueueUserWorkItem(t => 3 { 4 this.DoSomethingLong("btnThreadPool_Click"); 5 mre.Set(); 6 }); 7 mre.WaitOne();
// // 摘要: // 将事件状态设置为非终止,从而导致线程受阻。 // // 返回结果: // 如果该操作成功,则为 true;否则为 false。 // // 异常: // T:System.ObjectDisposedException: // 之前已在此 System.Threading.EventWaitHandle 上调用 System.Threading.WaitHandle.Close // 方法。 [SecuritySafeCritical] public bool Reset(); // // 摘要: // 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。 // // 返回结果: // 如果该操作成功,则为 true;否则为 false。 // // 异常: // T:System.ObjectDisposedException: // 之前已在此 System.Threading.EventWaitHandle 上调用 System.Threading.WaitHandle.Close // 方法。 [SecuritySafeCritical] public bool Set();
1 // 2 // 摘要: 3 // 阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号。 4 // 5 // 返回结果: 6 // 如果当前实例收到信号,则为 true。 如果当前实例永不发出信号,则 System.Threading.WaitHandle.WaitOne(System.Int32,System.Boolean) 7 // 永不返回。 8 // 9 // 异常: 10 // T:System.ObjectDisposedException: 11 // 当前实例已被释放。 12 // 13 // T:System.Threading.AbandonedMutexException: 14 // 等待完成,因为线程退出时未释放互斥体。 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。 15 // 16 // T:System.InvalidOperationException: 17 // 当前实例是透明代理 System.Threading.WaitHandle 另一个应用程序域中。 18 public virtual bool WaitOne();
3. 整段代码在WinForm下的执行:
1 #region btnThreadPool_Click 2 /// <summary> 3 /// 2.0 线程池 享元模式 单例模式 4 /// </summary> 5 /// <param name="sender"></param> 6 /// <param name="e"></param> 7 private void btnThreadPool_Click(object sender, EventArgs e) 8 { 9 Console.WriteLine($"****************btnThreadPool_Click Start {Thread.CurrentThread.ManagedThreadId}***************"); 10 { 11 ManualResetEvent mre = new ManualResetEvent(false);//信号量 12 ThreadPool.QueueUserWorkItem(t => 13 { 14 this.DoSomethingLong("btnThreadPool_Click"); 15 mre.Set(); 16 }); 17 mre.WaitOne(); 18 } 19 20 #region ManualResetEvent 21 { 22 ManualResetEvent mre = new ManualResetEvent(false);//false 关闭 23 new Action(() => 24 { 25 Thread.Sleep(5000); 26 Console.WriteLine("委托的异步调用"); 27 mre.Set();//打开 28 }).BeginInvoke(null, null); 29 30 mre.WaitOne(); 31 Console.WriteLine("12345"); 32 mre.Reset();//关闭 33 new Action(() => 34 { 35 Thread.Sleep(5000); 36 Console.WriteLine("委托的异步调用2"); 37 mre.Set();//打开 38 }).BeginInvoke(null, null); 39 mre.WaitOne(); 40 Console.WriteLine("23456"); 41 } 42 #endregion 43 44 #region PoolSet 45 ////ThreadPool.SetMaxThreads(8, 8);//最小也是核数 46 ////ThreadPool.SetMinThreads(8, 8); 47 //int workerThreads = 0; 48 //int ioThreads = 0; 49 //ThreadPool.GetMaxThreads(out workerThreads, out ioThreads); 50 //Console.WriteLine(String.Format("Max worker threads: {0}; Max I/O threads: {1}", workerThreads, ioThreads)); 51 52 //ThreadPool.GetMinThreads(out workerThreads, out ioThreads); 53 //Console.WriteLine(String.Format("Min worker threads: {0}; Min I/O threads: {1}", workerThreads, ioThreads)); 54 55 //ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads); 56 //Console.WriteLine(String.Format("Available worker threads: {0}; Available I/O threads: {1}", workerThreads, ioThreads)); 57 #endregion 58 59 Console.WriteLine($"****************btnThreadPool_Click End {Thread.CurrentThread.ManagedThreadId}***************"); 60 61 } 62 #endregion