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

第一套代码:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- namespace ProducerConsumerDemo
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- StopFlag = false;
- StartDemo();
- }
- private void button2_Click(object sender, EventArgs e)
- {
- StopFlag = true;
- }
- public class TaskInfo
- {
- public int Index;
- public TaskInfo()
- {
- }
- public TaskInfo(int index)
- {
- this.Index = index;
- }
- }
- private static bool StopFlag = false;
- private int ProducerNumber = 1;
- private int ConsumerNumber = 3;
- // 共用任务队列
- private Queue<TaskInfo> TaskQueue = new Queue<TaskInfo>();
- private Semaphore TaskSemaphore = new Semaphore(0, 256);
- private object myLock = new object();
- private void StartDemo()
- {
- StartProducer(ProducerNumber);
- Thread.Sleep(2000);
- StartConsumer(ConsumerNumber);
- }
- private void StartProducer(int num)
- {
- for (int i = 0; i < num; i++)
- {
- Thread t = new Thread(new ThreadStart(Producer));
- t.Name = "Producer_" + (i + 1);
- t.Start();
- }
- }
- private void StartConsumer(int num)
- {
- for (int i = 0; i < num; i++)
- {
- Thread t = new Thread(new ParameterizedThreadStart(this.Consumer));
- t.Name = "Consumer_" + (i + 1);
- t.IsBackground = true;
- t.Start(i + 1);
- }
- }
- // 线程间控件调用,需要使用委托
- public delegate void ProducerTextDelegate(string AddStr);
- public delegate void ComsumerTextDelegate(int Index, string AddStr);
- // 生产者
- private void Producer()
- {
- int i = 0;
- while (!StopFlag)
- {
- TaskInfo Task = new TaskInfo(++i);
- lock (myLock) // 任务队列为临界资源,需要锁
- {
- TaskQueue.Enqueue(Task);
- }
- TaskSemaphore.Release(1); // 每添加一个任务,信号量加1
- string AddText = String.Format("Task {0} was Produced.\r\n", Task.Index);
- ChangeProducerText(AddText); // 修改textBox输出
- Thread.Sleep(1000);
- }
- }
- // 消费者
- private void Consumer(object data)
- {
- int Index = (int)data;
- TaskInfo GetTask = null;
- while (true)
- {
- TaskSemaphore.WaitOne();
- lock (myLock)
- {
- GetTask = TaskQueue.Dequeue();
- }
- string AddStr = String.Format("Consumer {0} take Task {1}\r\n", Index, GetTask.Index);
- ChangeConsumerText(Index, AddStr);
- Random r = new Random();
- Thread.Sleep(r.Next(5) * 1000); // 休眠随机事件,模拟实际任务的每个任务的不同时常
- // 此处应为任务处理
- }
- }
- private void ChangeProducerText(string AddStr)
- {
- if (textBox1.InvokeRequired)
- {
- ProducerTextDelegate pd = new ProducerTextDelegate(ChangeProducerText);
- textBox1.Invoke(pd, new object[] { AddStr });
- }
- else
- {
- textBox1.AppendText(AddStr);
- }
- }
- private void ChangeConsumerText(int Index, string AddStr)
- {
- TextBox currentTextBox = null;
- switch (Index)
- {
- case 1:
- currentTextBox = this.textBox2;
- break;
- case 2:
- currentTextBox = this.textBox3;
- break;
- case 3:
- currentTextBox = this.textBox4;
- break;
- default:
- break;
- }
- if (currentTextBox.InvokeRequired)
- {
- ComsumerTextDelegate cd = new ComsumerTextDelegate(ChangeConsumerText);
- currentTextBox.Invoke(cd, new object[] { Index, AddStr });
- }
- else
- {
- currentTextBox.AppendText(AddStr);
- }
- }
- }
- }
第二套代码:
- // Form1.cs
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- namespace ProducerConsumerDemo
- {
- // 定义修改输出的委托
- public delegate void ShowTextDelegate(int Index, string Addstr);
- public partial class Form1 : Form
- {
- Work work = null;
- public Form1()
- {
- InitializeComponent();
- work = new Work();
- work.ShowTextEvent += new ShowTextDelegate(ChangeTextValue);
- }
- private void button1_Click(object sender, EventArgs e)
- {
- work.Start();
- }
- private void button2_Click(object sender, EventArgs e)
- {
- work.Stop();
- }
- // new Work 中再起的子线程调用的ShowTextDelegate委托事件,所以需要委托才能调用textBox控件
- public delegate void ChangeTextDelegate(int Index, string AddStr);
- private void ChangeTextValue(int Index, string AddStr)
- {
- TextBox ChangeTextBox = null;
- switch (Index)
- {
- case 1:
- ChangeTextBox = this.textBox1;
- break;
- case 2:
- ChangeTextBox = this.textBox2;
- break;
- case 3:
- ChangeTextBox = this.textBox3;
- break;
- case 4:
- ChangeTextBox = this.textBox4;
- break;
- default:
- break;
- }
- if (ChangeTextBox.InvokeRequired)
- {
- ChangeTextDelegate pd = new ChangeTextDelegate(ChangeTextValue);
- ChangeTextBox.Invoke(pd, new object[] { Index, AddStr });
- }
- else
- {
- ChangeTextBox.AppendText(AddStr);
- }
- }
- }
- }
- // Work.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- namespace ProducerConsumerDemo
- {
- public class Work
- {
- public Work()
- {
- StopFlag = false;
- }
- public void Start()
- {
- StopFlag = false;
- StartDemo();
- }
- public void Stop()
- {
- StopFlag = true;
- }
- public class TaskInfo
- {
- public int Index;
- public TaskInfo()
- {
- }
- public TaskInfo(int index)
- {
- this.Index = index;
- }
- }
- private static bool StopFlag = false;
- private int ProducerNumber = 1;
- private int ConsumerNumber = 3;
- private Queue<TaskInfo> TaskQueue = new Queue<TaskInfo>();
- private Semaphore TaskSemaphore = new Semaphore(0, 256);
- private object myLock = new object();
- public event ShowTextDelegate ShowTextEvent;
- private void StartDemo()
- {
- StartProducer(ProducerNumber);
- Thread.Sleep(2000);
- StartConsumer(ConsumerNumber);
- }
- private void StartProducer(int num)
- {
- for (int i = 0; i < num; i++)
- {
- Thread t = new Thread(new ThreadStart(Producer));
- t.Name = "Producer_" + (i + 1);
- t.Start();
- }
- }
- private void StartConsumer(int num)
- {
- for (int i = 0; i < num; i++)
- {
- Thread t = new Thread(new ParameterizedThreadStart(this.Consumer));
- t.Name = "Consumer_" + (i + 1);
- t.IsBackground = true;
- t.Start(i + 1);
- }
- }
- private void Producer()
- {
- int i = 0;
- while (!StopFlag)
- {
- TaskInfo Task = new TaskInfo(++i);
- lock (myLock)
- {
- TaskQueue.Enqueue(Task);
- }
- TaskSemaphore.Release(1);
- string AddText = String.Format("Task {0} was Produced.\r\n", Task.Index);
- ShowTextEvent.Invoke(1, AddText);
- Thread.Sleep(1000);
- }
- }
- private void Consumer(object data)
- {
- int Index = (int)data;
- TaskInfo GetTask = null;
- while (true)
- {
- TaskSemaphore.WaitOne();
- lock (myLock)
- {
- GetTask = TaskQueue.Dequeue();
- }
- string AddStr = String.Format("Consumer {0} take Task {1}\r\n", Index, GetTask.Index);
- ShowTextEvent.Invoke(Index + 1, AddStr);
- Random r = new Random();
- Thread.Sleep(r.Next(5) * 1000);
- }
- }
- }
- }
C# Producer Consumer (生产者消费者模式)demo的更多相关文章
- Java 生产者消费者模式详细分析
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 基于Java 生产者消费者模式(详细分析)
Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...
- 转:Task任务调度实现生产者消费者模式
我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等.在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者): 1. FIFO(先进先出) ...
- 使用BlockingQueue的生产者消费者模式
BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- 【多线程】--生产者消费者模式--synchronized版本
在实现生产者消费者模式之前,我们先了解一下线程的5种状态:被创建.运行.冻结.消亡.阻塞,如下图: 在Jdk1.5发布之前,我们实现生产者消费者模式一般使用synchronized + while循环 ...
- python3全栈开发-多进程的守护进程、进程同步、生产者消费者模式(重点)
一.守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes a ...
- Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码
说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...
- python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式
(1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...
- java多线程系列15 设计模式 生产者 - 消费者模式
生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...
随机推荐
- java 第五章 方法定义及调用
1.方法的定义 什么是方法 方法是完成某个功能的一组语句,通常将常用的功能写成一个方法 方法的定义 [访问控制符] [修饰符] 返回值类型 方法名( (参数类型 形式参数, ,参数类型 形式参数, , ...
- [bzoj1359][Baltic2009]Candy
给定N个数对$(T_i,S_i)$,表示时刻$S_i$时在位置$T_i$处出现一粒糖果.有一些机器人可供使用,每个机器人可花费一单位时间向相邻位置移动.要求用最少的机器人接到全部糖果.时刻0时机器人位 ...
- jmeter3.0生成html格式的dashboard性能测试结果
jmeter3.0以上支持生成dashboard的html报告,官网介绍:https://jmeter.apache.org/usermanual/generating-dashboard.html ...
- 『JavaScript』核心
弱类型语言 JavaScript是一种弱类型的语言.变量可以根据所赋的值改变类型.原始类型之间也可以进行类型转换.其弱类型的物质为其带来了极大的灵活性. 注意:原始类型使用值传递,复合类型使用引用传递 ...
- 命令行下对apk签名
l创建key,需要用到keytool.exe (位于jdk安装目录\bin目录下),使用产生的key对apk签名用到的是jarsigner.exe (位于jdk安装目录\bin目录下),把上两个软件所 ...
- SSH公钥认证(码云)
开发者向码云版本库写入最常用到的协议是 SSH 协议,因为 SSH 协议使用公钥认证,可以实现无口令访问,而若使用 HTTPS 协议每次身份认证时都需要提供口令.使用 SSH 公钥认证,就涉及到公钥的 ...
- MySQL☞create语句
几种常用的建表语句: 1.最简单的建表语句: create table 表名( 列名1 数据类型(长度), 列名2 数据类型(长度), ... ) 2.带主键的建表语句: CREATE TABLE 表 ...
- LeetCode 707 ——设计链表
1. 题目 2. 解答 用一个单链表来实现,只有一个头指针.因为不能建立哨兵结点,因此要特别注意是否在头结点处操作. class MyLinkedList { public: struct ListN ...
- 线段树——hdu1166敌兵布阵
一.题目回顾 题目链接:敌兵布阵 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个 ...
- java线程(3)——详解Callable、Future和FutureTask
回顾: 接上篇博客 java线程--三种创建线程的方式,这篇博客主要介绍第三种方式Callable和Future.比较继承Thread类和实现Runnable接口,接口更加灵活,使用更广泛.但这两种方 ...