Csharp/CSharp Tutorial/Thread/ThreadPool
Содержание
- 1 Available worker/IO threads
- 2 Max worker/IO threads in a ThreadPool
- 3 Min worker/IO threads in a ThreadPool
- 4 Registering wait callbacks for events
- 5 Scheduling work to occur on the thread-pool
- 6 ThreadPool Demo
- 7 Thread Pool Example
- 8 Use the system thread pool
- 9 Use ThreadPool
- 10 Use ThreadPool to implement a hello server
- 11 Using the thread pool and no arguments
- 12 Using the thread pool and providing an argument
- 13 Using ThreadPool Instead of Instantiating Threads Explicitly
Available worker/IO threads
<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; public class MainClass {
public static void Main() { int w, io; ThreadPool.GetAvailableThreads(out w, out io); Console.WriteLine(w); Console.WriteLine(io); }
}</source>
25 1000
Max worker/IO threads in a ThreadPool
<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; public class MainClass {
public static void Main() { int maxW, maxIO; ThreadPool.GetMaxThreads(out maxW, out maxIO); Console.WriteLine(maxW); Console.WriteLine(maxIO); }
}</source>
25 1000
Min worker/IO threads in a ThreadPool
<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; public class MainClass {
public static void Main() { int minW, minIO; ThreadPool.GetMinThreads(out minW, out minIO); Console.WriteLine(minW); Console.WriteLine(minIO); }
}</source>
1 1
Registering wait callbacks for events
<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; public class MainClass {
public static void Main() { using (EventWaitHandle ewh = new ManualResetEvent(false)) using (EventWaitHandle callbackDoneEvent = new ManualResetEvent(false)) { ThreadPool.RegisterWaitForSingleObject(ewh, delegate { Console.WriteLine("Callback fired: {0}", Thread.CurrentThread.ManagedThreadId); callbackDoneEvent.Set(); }, null, Timeout.Infinite, true); Console.WriteLine("Setting the event: {0}", Thread.CurrentThread.ManagedThreadId); ewh.Set(); callbackDoneEvent.WaitOne(); } }
}</source>
Setting the event: 1 Callback fired: 4
Scheduling work to occur on the thread-pool
<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; public class MainClass {
public static void Main() { using (ManualResetEvent mre = new ManualResetEvent(false)) { ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadPoolWorker), mre); Console.WriteLine("Continuing work on the main thread: {0}", Thread.CurrentThread.ManagedThreadId); mre.WaitOne(); } } private static void MyThreadPoolWorker(object state) { ManualResetEvent mre = (ManualResetEvent)state; Console.WriteLine("Work occurring on the thread-pool: {0}", Thread.CurrentThread.ManagedThreadId); // set the event to let our caller know we"re done: mre.Set(); }
}</source>
Work occurring on the thread-pool: 3 Continuing work on the main thread: 1
ThreadPool Demo
<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading;
public class Printer { private object lockToken = new object(); public void PrintNumbers() { lock (lockToken) { Console.WriteLine("-> {0} is executing PrintNumbers()",Thread.CurrentThread.Name); for (int i = 0; i < 10; i++) { Console.Write("{0}, ", i); Thread.Sleep(1000); } } } } class Program { static void Main(string[] args) { Console.WriteLine("Main thread started. ThreadID = {0}",Thread.CurrentThread.ManagedThreadId); Printer p = new Printer(); WaitCallback workItem = new WaitCallback(PrintTheNumbers); for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(workItem, p); } Console.ReadLine(); } static void PrintTheNumbers(object state) { Printer task = (Printer)state; task.PrintNumbers(); } }</source>
Thread Pool Example
<source lang="csharp">using System; using System.Threading; class MainClass {
public static void Main() { ThreadPool.QueueUserWorkItem(new WaitCallback(Counter)); ThreadPool.QueueUserWorkItem(new WaitCallback(Counter2)); for(int i = 0; i < 10; i++) { Console.WriteLine("main: {0}", i); Thread.Sleep(1000); } } static void Counter(object state) { for (int i = 0; i < 10; i++) { Console.WriteLine(" thread: {0}", i); Thread.Sleep(2000); } } static void Counter2(object state) { for (int i = 0; i < 10; i++) { Console.WriteLine(" thread2: {0}", i); Thread.Sleep(3000); } }
}</source>
Use the system thread pool
<source lang="csharp">using System; using System.Threading; class MainClass {
public static void Countdown(Object o) { for (int i = 1000; i > 0; i--) { Console.Write(i.ToString() + " "); } } public static void Main() { ThreadPool.QueueUserWorkItem(new WaitCallback(Countdown), null); }
}</source>
1000 999 998 997 996 995 994 993 992 991 990 989 988
Use ThreadPool
<source lang="csharp">using System; using System.Threading; class MainClass {
public static ManualResetEvent MyManualEvent = new ManualResetEvent(false); public static AutoResetEvent MyAutoEvent = new AutoResetEvent(false); static void Main(string[] args) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoBackgroundWorkManual)); MyManualEvent.WaitOne(); MyManualEvent.Reset(); ThreadPool.QueueUserWorkItem(new WaitCallback(DoBackgroundWorkAuto)); MyAutoEvent.WaitOne(); } public static void DoBackgroundWorkManual(Object state) { Console.WriteLine("Thread 1"); MyManualEvent.Set(); } public static void DoBackgroundWorkAuto(Object state) { Console.WriteLine("Thread 1"); MyAutoEvent.Set(); }
}</source>
Thread 1 Thread 1
Use ThreadPool to implement a hello server
<source lang="csharp">using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; class MainClass {
static void serve( Object obj ) { using ( Socket s = (Socket)obj ) { Encoding enc = Encoding.GetEncoding( "ASCII" ); Byte[] buff = enc.GetBytes( "hello" ); s.Send( buff ); s.Shutdown( SocketShutdown.Both ); s.Close(); } } [STAThread] static void Main(string[] args) { using ( Socket svr = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ) ) { svr.Bind( new IPEndPoint( IPAddress.Loopback, 8888 ) ); svr.Listen( 5 ); while ( true ) { Socket req = svr.Accept(); ThreadPool.QueueUserWorkItem( new WaitCallback( serve ), req ); } } }
}</source>
Using the thread pool and no arguments
<source lang="csharp">using System; using System.Threading; class MainClass {
public static void DisplayMessage(object state) { string config = state as string; Console.WriteLine(config); Thread.Sleep(1000); } public static void Main() { ThreadPool.QueueUserWorkItem(DisplayMessage); }
}</source>
info
Using the thread pool and providing an argument
<source lang="csharp">using System; using System.Threading; class MainClass {
public static void DisplayMessage(object state) { string config = state as string; Console.WriteLine(config); Thread.Sleep(1000); } public static void Main() { ThreadPool.QueueUserWorkItem(DisplayMessage, "info"); }
}</source>
Using ThreadPool Instead of Instantiating Threads Explicitly
<source lang="csharp">using System; using System.Threading; public class ThreadPools {
public const int Repetitions = 1000; public static void Main() { ThreadPool.QueueUserWorkItem(DoWork, "."); for (int count = 0; count < Repetitions; count++) { Console.Write("-"); } Thread.Sleep(1000); } public static void DoWork(object state) { for (int count = 0; count < Repetitions; count++) { Console.Write(state); } }
}</source>