rss· 投稿· 设为首页· 加入收藏· 繁體版
当前位置: 火魔网 » 程序开发 » C#

C#线程池实例

以下三个代码示例演示 QueueUserWorkItem 和 RegisterWaitForSingleObject 方法。

第一个示例使用 QueueUserWorkItem 方法将一个由 ThreadProc 方法表示的非常简单的任务排入队列。

using System;
using System.Threading;
public class Example {
     public static void Main() {
         // 将任务排队
         ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
       
         Console.WriteLine("Main thread does some work, then sleeps.");
         // 如果你注释掉这个Sleep, 而线程池使用后台线程,
          // 那么主线程将会停止运行,并在线程池任务运行之前退出
          // (这是一个简单的线程池运行环境例子)
         Thread.Sleep(1000);

         Console.WriteLine("Main thread exits.");
     }

     // 这是执行任务的线程子程序
     static void ThreadProc(Object stateInfo) {
         // 没有state对象被传递到QueueUserWorkItem, 所以
         // stateInfo是null.
         Console.WriteLine("Hello from the thread pool.");
     }
}

为 QueueUserWorkItem 提供任务数据
下面的代码示例使用 QueueUserWorkItem 方法将一个任务排队并为该任务提供数据。

using System;
using System.Threading;

// TaskInfo 类 为任务提供将在线程池线程中执行的 state 信息
public class TaskInfo {
     // 任务所需的State信息,这些类成员可以是任务需要的确定的只读属性,
     // 可读写属性,或者其它。
     public string Boilerplate;
     public int Value;

     // Public 构造函数提供一个非常简单途径用来接收任务所需要的信息
     public TaskInfo(string text, int number) {
         Boilerplate = text;
         Value = number;
     }
}

public class Example {
     public static void Main() {
         // 创建一个包含任务所需要信息的对象。
         TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);

         // 将任务排队并传入所需信息
         if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) {   
             Console.WriteLine("Main thread does some work, then sleeps.");

             // 如果你注释掉这个Sleep, 而线程池使用后台线程,
               // 那么主线程将会停止运行,并在线程池任务有机会运行之前退出
               // (这是一个简单的线程池运行环境例子)
             Thread.Sleep(1000);

             Console.WriteLine("Main thread exits.");
         }
         else {
             Console.WriteLine("Unable to queue ThreadPool request.");
         }
     }

     // 这个线程子程序执行独立的任务,在这里转换并打印一个非常简单的报告
     static void ThreadProc(Object stateInfo) {
         TaskInfo ti = (TaskInfo) stateInfo;
         Console.WriteLine(ti.Boilerplate, ti.Value);
     }
}

RegisterWaitForSingleObject
下面的示例演示几种线程处理功能。

・ 使用 RegisterWaitForSingleObject 方法将任务排队,以由 ThreadPool 线程执行。

・ 使用 AutoResetEvent 发出信号,通知执行任务。请参见 EventWaitHandle、AutoResetEvent 和 ManualResetEvent。

・ 使用 WaitOrTimerCallback 委托处理超时和信号。

・ 使用 RegisteredWaitHandle 取消排入队列的任务。

using System;
using System.Threading;

// TaskInfo 包含将要被回调(callback)的数据
public class TaskInfo {
     public RegisteredWaitHandle Handle = null;
     public string OtherInfo = "default";
}

public class Example {
     public static void Main(string[] args) {
         // 主线程使用 AutoResetEvent 通知执行回调方法的 wait 句柄(handle)
         AutoResetEvent ev = new AutoResetEvent(false);

         TaskInfo ti = new TaskInfo();
         ti.OtherInfo = "First task";
         // TaskInfo对象包含了为任务返回RegisterWaitForSingleObject的注册等待句柄(handle)
         // 这允许当对象一旦被通知就终止等待操作。(见 WaitProc).
         ti.Handle = ThreadPool.RegisterWaitForSingleObject(
             ev,
             new WaitOrTimerCallback(WaitProc),
             ti,
             1000,
             false
         );

         // 主线程等待三秒钟,用以示范排队线程超时的情况,然后通知它。
         Thread.Sleep(3100);
         Console.WriteLine("Main thread signals.");
         ev.Set();

         // 主线程休眠(sleeps),应该能给回调(callback)方法足够的时候去执行它。
         // 如果你注释掉这行,程序通常会在线程池线程被执行前退出。
         Thread.Sleep(1000);
         // 如果你开始一个自己的线程,你可以调用 Thread.Join() 来等待它完成。
         // 这个选项在线程池线程里不可用。
     }
  
     // 当注册等待超时,或者当等待句柄(WaitHandle――在这个例子里是AutoResetEvent)被通知时,
     // 将会执行这个回调(callback)方法,
     // WaitProc 反注册等待句柄(WaitHandle) the first time the event is
     // signaled.
     public static void WaitProc(object state, bool timedOut) {
         // state 对象必须传入正确的类型,因为 WaitOrTimerCallback 委托(delegate)
         // 明确指出的对象的类型。
         TaskInfo ti = (TaskInfo) state;

         string cause = "TIMED OUT";
         if (!timedOut) {
             cause = "SIGNALED";
             // 如果这个回调(callback)方法被执行是因为等待句柄(WaitHandle)通知,
             // 停止执行接下来的回调(callback )方法, 并反注册等待句柄(WaitHandle)
             if (ti.Handle != null)
                 ti.Handle.Unregister(null);
         }

         Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.",
             ti.OtherInfo,
             Thread.CurrentThread.GetHashCode().ToString(),
             cause
         );
     }
}

  • using System;   
  • using System.Collections.Generic;   
  • using System.Text;   
  • using System.Threading;   
  •   
  •   
  •   
  • class count   
  • {   
  •     public count(int from, ManualResetEvent e)   
  •     {   
  •         _from = from;   
  •         _done_event = e;   
  •     }   
  •     private int _from;   
  •     private int _sum;   
  •     private ManualResetEvent _done_event;   
  •     public int docount(int _from)   
  •     {   
  •         int sum = 0;   
  •         for (int i = 0; i <= _from; i++)   
  •         {   
  •             sum += i;   
  •         }   
  •         return sum;   
  •     }   
  •     public void ThreadPoolCallback(Object threadContext)   
  •     {   
  •         int threadIndex = (int)threadContext;   
  •         Console.WriteLine("Thread {0} started", threadIndex);   
  •         _sum = docount(_from);   
  •         Console.WriteLine("Thread count result is {0}", _sum);   
  •         _done_event.Set();   
  •     }   
  •   
  • }   
  •   
  • public class ThreadPoolEx   
  • {   
  •     static void Main()   
  •     {   
  •         const int times = 10;   
  •         ManualResetEvent[] mre = new ManualResetEvent[times];   
  •         Random r = new Random();   
  •         Console.WriteLine("Launch {0} tasks", times);   
  •         for (int i = 0; i < times; i++)   
  •         {   
  •             mre[i] = new ManualResetEvent(false);   
  •             count c = new count(r.Next(1, 1000), mre[i]);   
  •             ThreadPool.QueueUserWorkItem(c.ThreadPoolCallback, i);   
  •   
  •         }   
  •         WaitHandle.WaitAll(mre);   
  •         Console.WriteLine("All threads finished.");   
  •   
  •     }   
  •   
  •   
  • 顶一下
    (0)
    踩一下
    (1)