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

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

第一套代码:

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

第二套代码:

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

C# Producer Consumer (生产者消费者模式)demo的更多相关文章

  1. Java 生产者消费者模式详细分析

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  2. 基于Java 生产者消费者模式(详细分析)

    Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...

  3. 转:Task任务调度实现生产者消费者模式

    我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等.在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者): 1. FIFO(先进先出)      ...

  4. 使用BlockingQueue的生产者消费者模式

    BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...

  5. Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...

  6. 【多线程】--生产者消费者模式--synchronized版本

    在实现生产者消费者模式之前,我们先了解一下线程的5种状态:被创建.运行.冻结.消亡.阻塞,如下图: 在Jdk1.5发布之前,我们实现生产者消费者模式一般使用synchronized + while循环 ...

  7. python3全栈开发-多进程的守护进程、进程同步、生产者消费者模式(重点)

    一.守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes a ...

  8. Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码

    说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...

  9. python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式

    (1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...

  10. java多线程系列15 设计模式 生产者 - 消费者模式

    生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...

随机推荐

  1. hoj第三场G-manhattanp ositioning system

    ---恢复内容开始--- 一.题意 在二维坐标系内,给定若干个点和目标点距离该点的曼哈顿距离,求是否存在唯一解使得目标点坐标为整数. 二.题解 重新思考题目模型,考虑曼哈顿距离一定时,几何含义为,以给 ...

  2. VS2017 远程调试小记

    VS2017 远程调试小记 支持windows\linux\macos, 直接连接项目点的上线版本代码进行调试.保证bug在同个环境下实时追踪. 注意点 双方的 msvsmon.exe版本需一致,最好 ...

  3. js 实现字符串转日期进行比较大小

    代码如下 var a = '2016-01-01 12:12:12'; var b = '2016-01-01 12:12:13'; var al = new Date(a).getTime(); v ...

  4. 6 wireshark 安装使用 数据包抓取

    1.wireshark安装 2.开始使用 3.界面详情 4. 数据包抓取 5.过滤数据

  5. MyEclipse10安装checkStyle与findBugs插件--详细完美结局-费元星

    本人QQ:971751392(屌丝一枚) Myeclipse10安装checkStyle与findBugs插件详细完美结局方案: 资源一: http://download.csdn.net/detai ...

  6. Java与C++进行系统间交互:Protocol Buffer

    在一次项目中,因笔者负责的java端应用需要与公司C++系统进行交互,公司选定Protocol Buffer方案,故简单的了解一下 有需要的可以看一下其他作者的文章,了解一下Protobuf: htt ...

  7. XPivot 用户手册及版本更新公示

    此文仅介绍XPivot的通用功能,如有对项目中定制的高级功能感兴趣的可留言讨论 XPivot当前版本v2.2 [2015-04-20发布] v2.1 下载链接: http://pan.baidu.co ...

  8. 【个人训练】The Cow Lexicon(POJ-3267)

    继续大战dp.2018年11月30日修订,更新一下现在看到这个题目的理解(ps:就现在,poj又503了). 题意分析 这条题目的大意是这样的,问一字符串内最少删去多少的字符使其由给定的若干字符串构成 ...

  9. 常用模块(xml)

    XML(可扩展性标记语言)是一种非常常用的文件类型,主要用于存储和传输数据.在编程中,对XML的操作也非常常见. 本文根据python库文档中的xml.etree.ElementTree类来进行介绍X ...

  10. restAssured + TestNG测试接口,以下是一个get 请求。

    package Elaine.Test.G.APITest; import org.testng.Assert;import org.testng.annotations.BeforeTest;imp ...