Csharp/CSharp Tutorial/Thread/ThreadPool

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

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>