Csharp/CSharp Tutorial/Thread/ThreadPool

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

Available worker/IO threads

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);
    }
}
25
1000

Max worker/IO threads in a ThreadPool

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);
    }
}
25
1000

Min worker/IO threads in a ThreadPool

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);
    }
}
1
1

Registering wait callbacks for events

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();
        }
    }
}
Setting the event: 1
Callback fired: 4

Scheduling work to occur on the thread-pool

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();
    }
}
Work occurring on the thread-pool: 3
Continuing work on the main thread: 1

ThreadPool Demo

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();
    }
  }

Thread Pool Example

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);
      }
   }
}

Use the system thread pool

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);
  }
}
1000 999 998 997 996 995 994 993 992 991 990 989 988

Use ThreadPool

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();
  }
}
Thread 1
Thread 1

Use ThreadPool to implement a hello server

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 );
      }
    }
  }
}

Using the thread pool and no arguments

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

Using the thread pool and providing an argument

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");
    }
}

Using ThreadPool Instead of Instantiating Threads Explicitly

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);
      }
  }
}