• 线程池用法的改进


    引用: http://blog.csdn.net/jhycjhyc/article/details/7243728

    MSDN关于使用线程池的一个例子(http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx).程序如下:

     

     1 public class Fibonacci
     2 {
     3     public int N { get { return _n; } }
     4     private int _n;
     5 
     6     public int FibOfN { get { return _fibOfN; } }
     7     private int _fibOfN;
     8 
     9     private ManualResetEvent _doneEvent;
    10 
    11     public Fibonacci(int n, ManualResetEvent doneEvent)
    12     {
    13         _n = n;
    14         _doneEvent = doneEvent;
    15     }
    16 
    17     // Wrapper method for use with thread pool.
    18     public void ThreadPoolCallback(Object threadContext)
    19     {
    20                 
    21         int threadIndex = (int)threadContext;
    22         Console.WriteLine("thread {0} started...", threadIndex);
    23         _fibOfN = Calculate(_n);
    24         Console.WriteLine("thread {0} result calculated...", threadIndex);
    25         _doneEvent.Set();
    26     }
    27 
    28     // Recursive method that calculates the Nth Fibonacci number.
    29     public int Calculate(int n)
    30     {
    31         //Thread thread = Thread.CurrentThread;
    32         //Console.WriteLine("[{0}] Calculate:{1}...", thread.ManagedThreadId, n);
    33         if (n <= 1)
    34         {
    35             return n;
    36         }
    37         return Calculate(n - 1) + Calculate(n - 2);
    38     }
    39 
    40 }
    View Code

     

    调用方法:

     1 static void Main(string[] args)
     2 {
     3     const int FibonacciCalculations = 2;  //最大只能64,超出会报错
     4 
     5     // One event is used for each Fibonacci object
     6     ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
     7     Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
     8     Random r = new Random();
     9 
    10     // Configure and launch threads using ThreadPool:
    11     Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
    12     for (int i = 0; i < FibonacciCalculations; i++)
    13     {
    14         doneEvents[i] = new ManualResetEvent(false);
    15         Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);
    16         fibArray[i] = f;
    17         ThreadPool.QueueUserWorkItem(new WaitCallback(f.ThreadPoolCallback), i);
    18     }
    19 
    20     // Wait for all threads in pool to calculation...
    21     WaitHandle.WaitAll(doneEvents);
    22     Console.WriteLine("All calculations are complete.");
    23 
    24     // Display the results...
    25     for (int i = 0; i < FibonacciCalculations; i++)
    26     {
    27         Fibonacci f = fibArray[i];
    28         Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
    29     }
    30     Console.ReadLine();
    31 }
    View Code

    以上例子是利用多线程的线程池技术进行批处理的经典范例,在实际应用中稍加改动就可以实现自己所需的功能,但遗憾的是,如果批处理的任务数大于64个时,程序运行就会出错,提示"WaitHandles 的数目必须少于或等于 64 ."以上例而言,"const int FibonacciCalculations = 10;"改为"const int FibonacciCalculations = 65;"后再运行就会出错,这确实是一个不足,因为在实际工作中很多情况下需要用线程池技术批量处理64个以上的任务,怎么办呢?经过分析,对以上程序做了一些改动,解决了这个问题,而且程序的结构更简单,也不再需要使用 ManualResetEvent 对象,修改后的程序如下

     

     1 public class Fibonacci_02
     2 {
     3     public int ifdone = 0;   //注意这里
     4 
     5     public int N { get { return _n; } }
     6     private int _n;
     7 
     8     public int FibOfN { get { return _fibOfN; } }
     9     private int _fibOfN;
    10 
    11     public Fibonacci_02(int n)
    12     {
    13         _n = n;
    14     }
    15 
    16     // Wrapper method for use with thread pool.
    17     public void ThreadPoolCallback(Object threadContext)
    18     {
    19         int threadIndex = (int)threadContext;
    20         Console.WriteLine("thread {0} started...", threadIndex);
    21         _fibOfN = Calculate(_n);
    22         Console.WriteLine("thread {0} result calculated...", threadIndex);
    23 
    24         ifdone = 1;
    25     }
    26 
    27     // Recursive method that calculates the Nth Fibonacci number.
    28     public int Calculate(int n)
    29     {
    30         //Thread thread = Thread.CurrentThread;
    31         //Console.WriteLine("[{0}] Calculate:{1}...", thread.ManagedThreadId, n);
    32         if (n <= 1)
    33         {
    34             return n;
    35         }
    36         Thread.Sleep(1);
    37         return Calculate(n - 1) + Calculate(n - 2);
    38     }
    39 }
    View Code

     

    调用方法:

     1 static void Main(string[] args)
     2 {
     3     const int FibonacciCalculations = 2;//可以无限大
     4 
     5     // One event is used for each Fibonacci object
     6     Fibonacci_02[] fibArray = new Fibonacci_02[FibonacciCalculations];
     7     Random r = new Random();
     8 
     9     // Configure and launch threads using ThreadPool:
    10     Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
    11     for (int i = 0; i < FibonacciCalculations; i++)
    12     {
    13         Fibonacci_02 f = new Fibonacci_02(r.Next(20, 40));
    14         fibArray[i] = f;
    15         ThreadPool.QueueUserWorkItem(new WaitCallback(f.ThreadPoolCallback), i);
    16     }
    17 
    18     // Wait for all threads in pool to calculation...
    19     //注意这里
    20     while (true)
    21     {
    22         int counts = 0;
    23         for (int i = 0; i < FibonacciCalculations; i++) counts = counts + fibArray[i].ifdone;
    24         if (counts == FibonacciCalculations) break;
    25     }
    26     Console.WriteLine("All calculations are complete.");
    27 
    28     // Display the results...
    29     for (int i = 0; i < FibonacciCalculations; i++)
    30     {
    31         Fibonacci_02 f = fibArray[i];
    32         Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
    33     }
    34     Console.ReadLine();
    35 }
    View Code

     

     

  • 相关阅读:
    Visual Studio 2008中 在工具栏上添加"在文件中查找"
    WPF 获得文件夹路径/浏览文件夹路径
    WPF ListBox
    如何:创建和使用 C# DLL(C# 编程指南)
    (收藏)《博客园精华集》分类索引
    WPF 文件级资源(类似与使用CSS文件,然后引用CSS文件)
    [WPF/Silverlight]让INotifyPropertyChanged的实现更优雅一些
    WPF 动画
    WPF 鼠标移动到图片变大,移开还原,单击触发事件效果
    Regsvr32.exe 用法
  • 原文地址:https://www.cnblogs.com/xzxBlog/p/4605245.html
Copyright © 2020-2023  润新知