C# Producer Consumer (生产者消费者模式)demo

  第一套代码将producer Consumer的逻辑写到from类里了,方便在demo的显示界面动态显示模拟生产和消费的过程。
     第二套代码将producer Consumer的逻辑单独写到一个类中,使用委托的方法在from中回显生产消费的过程。
     Demo中均以3个线程作为消费者,1个线程作为生产者为例。 
     由于是C#新手,有不对的地方望不吝赐教。


     先贴下窗口截图,动态生产消费进度显示

第一套代码:

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Threading;  
  10.   
  11. namespace ProducerConsumerDemo  
  12. {  
  13.     public partial class Form1 : Form  
  14.     {  
  15.   
  16.         public Form1()  
  17.         {  
  18.             InitializeComponent();  
  19.         }  
  20.   
  21.         private void button1_Click(object sender, EventArgs e)  
  22.         {  
  23.             StopFlag = false;  
  24.             StartDemo();  
  25.         }  
  26.   
  27.         private void button2_Click(object sender, EventArgs e)  
  28.         {  
  29.             StopFlag = true;  
  30.         }  
  31.   
  32.         public class TaskInfo  
  33.         {  
  34.             public int Index;  
  35.   
  36.             public TaskInfo()  
  37.             {  
  38.             }  
  39.   
  40.             public TaskInfo(int index)  
  41.             {  
  42.                 this.Index = index;  
  43.             }  
  44.         }  
  45.   
  46.         private static bool StopFlag = false;  
  47.         private int ProducerNumber = 1;  
  48.         private int ConsumerNumber = 3;  
  49.   
  50.         // 共用任务队列  
  51.         private Queue<TaskInfo> TaskQueue = new Queue<TaskInfo>();  
  52.         private Semaphore TaskSemaphore = new Semaphore(0, 256);  
  53.   
  54.         private object myLock = new object();  
  55.   
  56.         private void StartDemo()  
  57.         {  
  58.             StartProducer(ProducerNumber);  
  59.             Thread.Sleep(2000);  
  60.             StartConsumer(ConsumerNumber);  
  61.         }  
  62.   
  63.         private void StartProducer(int num)  
  64.         {  
  65.             for (int i = 0; i < num; i++)  
  66.             {  
  67.                 Thread t = new Thread(new ThreadStart(Producer));  
  68.                 t.Name = "Producer_" + (i + 1);  
  69.                 t.Start();  
  70.             }  
  71.         }  
  72.   
  73.         private void StartConsumer(int num)  
  74.         {  
  75.             for (int i = 0; i < num; i++)  
  76.             {  
  77.                 Thread t = new Thread(new ParameterizedThreadStart(this.Consumer));  
  78.                 t.Name = "Consumer_" + (i + 1);  
  79.                 t.IsBackground = true;  
  80.                 t.Start(i + 1);  
  81.             }  
  82.         }  
  83.   
  84.         // 线程间控件调用,需要使用委托  
  85.         public delegate void ProducerTextDelegate(string AddStr);  
  86.         public delegate void ComsumerTextDelegate(int Index, string AddStr);  
  87.   
  88.         // 生产者  
  89.         private void Producer()  
  90.         {  
  91.             int i = 0;  
  92.             while (!StopFlag)  
  93.             {  
  94.                 TaskInfo Task = new TaskInfo(++i);  
  95.                 lock (myLock)   // 任务队列为临界资源,需要锁  
  96.                 {  
  97.                     TaskQueue.Enqueue(Task);  
  98.                 }  
  99.                 TaskSemaphore.Release(1);   // 每添加一个任务,信号量加1  
  100.    
  101.                 string AddText = String.Format("Task {0} was Produced. ", Task.Index);  
  102.                 ChangeProducerText(AddText);    // 修改textBox输出  
  103.   
  104.                 Thread.Sleep(1000);  
  105.             }  
  106.         }  
  107.   
  108.         // 消费者  
  109.         private void Consumer(object data)  
  110.         {  
  111.             int Index = (int)data;  
  112.             TaskInfo GetTask = null;  
  113.   
  114.             while (true)  
  115.             {  
  116.                 TaskSemaphore.WaitOne();  
  117.                 lock (myLock)  
  118.                 {  
  119.                     GetTask = TaskQueue.Dequeue();  
  120.                 }  
  121.   
  122.                 string AddStr = String.Format("Consumer {0} take Task {1} ", Index, GetTask.Index);  
  123.   
  124.                 ChangeConsumerText(Index, AddStr);  
  125.                 Random r = new Random();  
  126.                 Thread.Sleep(r.Next(5) * 1000);     // 休眠随机事件,模拟实际任务的每个任务的不同时常  
  127.                 // 此处应为任务处理  
  128.             }  
  129.         }  
  130.   
  131.         private void ChangeProducerText(string AddStr)  
  132.         {  
  133.             if (textBox1.InvokeRequired)  
  134.             {  
  135.                 ProducerTextDelegate pd = new ProducerTextDelegate(ChangeProducerText);  
  136.                 textBox1.Invoke(pd, new object[] { AddStr });  
  137.             }  
  138.             else  
  139.             {  
  140.                 textBox1.AppendText(AddStr);  
  141.             }  
  142.         }  
  143.   
  144.         private void ChangeConsumerText(int Index, string AddStr)  
  145.         {  
  146.             TextBox currentTextBox = null;  
  147.             switch (Index)  
  148.             {  
  149.                 case 1:  
  150.                     currentTextBox = this.textBox2;  
  151.                     break;  
  152.                 case 2:  
  153.                     currentTextBox = this.textBox3;  
  154.                     break;  
  155.                 case 3:  
  156.                     currentTextBox = this.textBox4;  
  157.                     break;  
  158.                 default:  
  159.                     break;  
  160.             }  
  161.   
  162.             if (currentTextBox.InvokeRequired)  
  163.             {  
  164.                 ComsumerTextDelegate cd = new ComsumerTextDelegate(ChangeConsumerText);  
  165.                 currentTextBox.Invoke(cd, new object[] { Index, AddStr });  
  166.             }  
  167.             else  
  168.             {  
  169.                 currentTextBox.AppendText(AddStr);  
  170.             }  
  171.         }  
  172.     }  
  173. }  


第二套代码:

[csharp] view plaincopy
 
    1. // Form1.cs  
    2. using System;  
    3. using System.Collections.Generic;  
    4. using System.ComponentModel;  
    5. using System.Data;  
    6. using System.Drawing;  
    7. using System.Linq;  
    8. using System.Text;  
    9. using System.Windows.Forms;  
    10. using System.Threading;  
    11.   
    12. namespace ProducerConsumerDemo  
    13. {  
    14.     // 定义修改输出的委托  
    15.     public delegate void ShowTextDelegate(int Index, string Addstr);  
    16.   
    17.     public partial class Form1 : Form  
    18.     {  
    19.         Work work = null;  
    20.   
    21.         public Form1()  
    22.         {  
    23.             InitializeComponent();  
    24.             work = new Work();  
    25.             work.ShowTextEvent += new ShowTextDelegate(ChangeTextValue);  
    26.         }  
    27.   
    28.         private void button1_Click(object sender, EventArgs e)  
    29.         {   
    30.             work.Start();  
    31.         }  
    32.   
    33.         private void button2_Click(object sender, EventArgs e)  
    34.         {  
    35.             work.Stop();  
    36.         }  
    37.   
    38.         // new Work 中再起的子线程调用的ShowTextDelegate委托事件,所以需要委托才能调用textBox控件  
    39.         public delegate void ChangeTextDelegate(int Index, string AddStr);  
    40.   
    41.         private void ChangeTextValue(int Index, string AddStr)  
    42.         {  
    43.             TextBox ChangeTextBox = null;  
    44.             switch (Index)  
    45.             {  
    46.                 case 1:  
    47.                     ChangeTextBox = this.textBox1;  
    48.                     break;  
    49.                 case 2:  
    50.                     ChangeTextBox = this.textBox2;  
    51.                     break;  
    52.                 case 3:  
    53.                     ChangeTextBox = this.textBox3;  
    54.                     break;  
    55.                 case 4:  
    56.                     ChangeTextBox = this.textBox4;  
    57.                     break;  
    58.                 default:  
    59.                     break;  
    60.             }  
    61.   
    62.             if (ChangeTextBox.InvokeRequired)  
    63.             {  
    64.                 ChangeTextDelegate pd = new ChangeTextDelegate(ChangeTextValue);  
    65.                 ChangeTextBox.Invoke(pd, new object[] { Index, AddStr });  
    66.             }  
    67.             else  
    68.             {  
    69.                 ChangeTextBox.AppendText(AddStr);  
    70.             }  
    71.   
    72.         }  
    73.     }  
    74.   
    75. }  
    76.   
    77. // Work.cs  
    78. using System;  
    79. using System.Collections.Generic;  
    80. using System.Linq;  
    81. using System.Text;  
    82. using System.Threading;  
    83.   
    84. namespace ProducerConsumerDemo  
    85. {  
    86.     public class Work  
    87.     {  
    88.         public Work()  
    89.         {  
    90.             StopFlag = false;  
    91.         }  
    92.   
    93.         public void Start()  
    94.         {  
    95.             StopFlag = false;  
    96.             StartDemo();  
    97.         }  
    98.   
    99.         public void Stop()  
    100.         {  
    101.             StopFlag = true;  
    102.         }  
    103.   
    104.         public class TaskInfo  
    105.         {  
    106.             public int Index;  
    107.   
    108.             public TaskInfo()  
    109.             {  
    110.             }  
    111.   
    112.             public TaskInfo(int index)  
    113.             {  
    114.                 this.Index = index;  
    115.             }  
    116.         }  
    117.   
    118.         private static bool StopFlag = false;  
    119.         private int ProducerNumber = 1;  
    120.         private int ConsumerNumber = 3;  
    121.   
    122.         private Queue<TaskInfo> TaskQueue = new Queue<TaskInfo>();  
    123.         private Semaphore TaskSemaphore = new Semaphore(0, 256);  
    124.   
    125.         private object myLock = new object();  
    126.   
    127.         public event ShowTextDelegate ShowTextEvent;  
    128.   
    129.         private void StartDemo()  
    130.         {  
    131.   
    132.   
    133.             StartProducer(ProducerNumber);  
    134.             Thread.Sleep(2000);  
    135.             StartConsumer(ConsumerNumber);  
    136.         }  
    137.   
    138.         private void StartProducer(int num)  
    139.         {  
    140.             for (int i = 0; i < num; i++)  
    141.             {  
    142.                 Thread t = new Thread(new ThreadStart(Producer));  
    143.                 t.Name = "Producer_" + (i + 1);  
    144.                 t.Start();  
    145.             }  
    146.         }  
    147.   
    148.         private void StartConsumer(int num)  
    149.         {  
    150.             for (int i = 0; i < num; i++)  
    151.             {  
    152.                 Thread t = new Thread(new ParameterizedThreadStart(this.Consumer));  
    153.                 t.Name = "Consumer_" + (i + 1);  
    154.                 t.IsBackground = true;  
    155.                 t.Start(i + 1);  
    156.             }  
    157.         }  
    158.   
    159.         private void Producer()  
    160.         {  
    161.             int i = 0;  
    162.             while (!StopFlag)  
    163.             {  
    164.                 TaskInfo Task = new TaskInfo(++i);  
    165.                 lock (myLock)  
    166.                 {  
    167.                     TaskQueue.Enqueue(Task);  
    168.                 }  
    169.                 TaskSemaphore.Release(1);  
    170.   
    171.                 string AddText = String.Format("Task {0} was Produced. ", Task.Index);  
    172.                 ShowTextEvent.Invoke(1, AddText);  
    173.   
    174.                 Thread.Sleep(1000);  
    175.             }  
    176.         }  
    177.   
    178.         private void Consumer(object data)  
    179.         {  
    180.             int Index = (int)data;  
    181.             TaskInfo GetTask = null;  
    182.   
    183.             while (true)  
    184.             {  
    185.                 TaskSemaphore.WaitOne();  
    186.                 lock (myLock)  
    187.                 {  
    188.                     GetTask = TaskQueue.Dequeue();  
    189.                 }  
    190.   
    191.                 string AddStr = String.Format("Consumer {0} take Task {1} ", Index, GetTask.Index);  
    192.                 ShowTextEvent.Invoke(Index + 1, AddStr);  
    193.                 Random r = new Random();  
    194.                 Thread.Sleep(r.Next(5) * 1000);  
    195.             }  
    196.         }  
    197.     }  
    198. }  
原文地址:https://www.cnblogs.com/bdbw2012/p/3829198.html