C#感觉比MFC和QT好用多了,决定以后除了特殊要求外都用C#开发:)。记录一下用C#实现生产者消费者模式吧。 代码: using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Threading;
namespace Producer_Consumer_Test { public partial class Form1 : Form { bool NeedsStop = false; bool NeedsStop1 = false; bool NeedsStop2 = false; bool NeedsStop3 = false; bool NeedsStop4 = false; Object thisLock = new Object(); List<int> RandomList = new List<int>(); public Form1() { InitializeComponent(); } /***********************************************生产者按钮与消费者按钮**********************************************/ private void btn_Use_Start_Click(object sender, EventArgs e) { btn_Use_Start.Text = (btn_Use_Start.Text == "开始消费") ? "停止消费" : "开始消费"; if (btn_Use_Start.Text == "停止消费") { Thread Mythread1 = new Thread(Consumer1); Mythread1.Start(); Thread Mythread2 = new Thread(Consumer2); Mythread2.Start(); NeedsStop = false; } else NeedsStop = true; } private void btn_Producer1_Start_Click(object sender, EventArgs e) {
btn_Producer1_Start.Text = (btn_Producer1_Start.Text == "开始生产") ? "停止生产" : "开始生产"; if (btn_Producer1_Start.Text == "停止生产") { Thread Mythread = new Thread(Thread1_Random); Mythread.Start(); NeedsStop1 = false; } else NeedsStop1 = true; }
private void btn_Producer2_Start_Click(object sender, EventArgs e) { btn_Producer2_Start.Text = (btn_Producer2_Start.Text == "开始生产") ? "停止生产" : "开始生产"; if (btn_Producer2_Start.Text == "停止生产") { Thread Mythread = new Thread(Thread2_Random); Mythread.Start(); NeedsStop2 = false; } else NeedsStop2 = true; }
private void btn_Producer3_Start_Click(object sender, EventArgs e) { btn_Producer3_Start.Text = (btn_Producer3_Start.Text == "开始生产") ? "停止生产" : "开始生产"; if (btn_Producer3_Start.Text == "停止生产") { Thread Mythread = new Thread(Thread3_Random); Mythread.Start(); NeedsStop3 = false; } else NeedsStop3 = true; }
private void btn_Producer4_Start_Click(object sender, EventArgs e) { btn_Producer4_Start.Text = (btn_Producer4_Start.Text == "开始生产") ? "停止生产" : "开始生产"; if (btn_Producer4_Start.Text == "停止生产") { Thread Mythread = new Thread(Thread4_Random); Mythread.Start(); NeedsStop4 = false; } else NeedsStop4 = true;
} /***********************************************线程函数**********************************************/ private void Thread1_Random() { MyRandom Ran = new MyRandom(); Ran.IsEven += new IsEvenEvent(SaveData); while (true) { Ran.run_Random(); if (NeedsStop1 == true) break; Thread.Sleep(500); } } private void Thread2_Random() { MyRandom Ran = new MyRandom(); Ran.IsEven += new IsEvenEvent(SaveData); while (true) { Ran.run_Random(); if (NeedsStop2 == true) break; Thread.Sleep(500); } } private void Thread3_Random() { MyRandom Ran = new MyRandom(); Ran.IsEven += new IsEvenEvent(SaveData); while (true) { Ran.run_Random(); if (NeedsStop3 == true) break; Thread.Sleep(500); } } private void Thread4_Random() { MyRandom Ran = new MyRandom(); Ran.IsEven += new IsEvenEvent(SaveData); while (true) { Ran.run_Random(); if (NeedsStop4 == true) break; Thread.Sleep(500); } } //此函数将四个生产者线程产生的随机数压栈,此处用互斥锁锁住防止多线程同时访问 private void SaveData(object Sender, IsEvenEventArgs e) { lock (thisLock) { RandomList.Add(e.Random); } } //消费者处理函数,数据处理区用锁锁住 private void Consumer1() { while (true) { if (NeedsStop == true) break; Thread.Sleep(100); lock (thisLock) { if (RandomList.Count == 0) continue; if (RandomList.ElementAt(0) % 2 == 0) { if (textBox_Consumer1.IsHandleCreated)//添加此举解决异常2020.12.30) { textBox_Consumer1.Invoke ( new Action ( delegate { textBox_Consumer1.Text += RandomList.ElementAt(0).ToString() + "\r\n"; RandomList.RemoveAt(0); textBox_Consumer1.Focus();//获取焦点 textBox_Consumer1.Select(this.textBox_Consumer1.TextLength, 0);//光标定位到文本最后 textBox_Consumer1.ScrollToCaret();//滚动到光标处 } ) ); } } else RandomList.RemoveAt(0); } } } private void Consumer2() { while (true) { if (NeedsStop == true) break; Thread.Sleep(100); lock (thisLock) { if (RandomList.Count == 0) continue; if (RandomList.ElementAt(0) % 2 == 0) { if (textBox_Consumer2.IsHandleCreated)//添加此举解决异常2020.12.30) { textBox_Consumer2.Invoke ( new Action ( delegate { textBox_Consumer2.Text += RandomList.ElementAt(0).ToString() + "\r\n"; RandomList.RemoveAt(0); textBox_Consumer2.Focus();//获取焦点 textBox_Consumer2.Select(this.textBox_Consumer2.TextLength, 0);//光标定位到文本最后 textBox_Consumer2.ScrollToCaret();//滚动到光标处 } ) ); } } else RandomList.RemoveAt(0); } } } } }
引用的类: using System;
namespace Producer_Consumer_Test { //1.声明一个新的事件传递参数函数,继承EventArgs类,是用于触发事件时传递参数 public class IsEvenEventArgs : EventArgs { public int Random = 0; public IsEvenEventArgs(int inputRandom) { Random = inputRandom; } } //2.声明变更事件的委托类型,需要传递的参数由第一步中声明 public delegate void IsEvenEvent(object Sender, IsEvenEventArgs e); class MyRandom { //3.声明状态更改事件的名称,使用的是第二步中的委托类型 public event IsEvenEvent IsEven; public void run_Random() { Random rd = new Random(); int rad = rd.Next(1, 10000); //4.在需要的地方拉起事件,同时将参数传递进去 if (rad % 2 == 0) IsEven(this, new IsEvenEventArgs(rad)); } }
}
先提一下生产随机数的类吧,自定义了一个事件,生成随机数的事件将偶数传回。 |
|
来自: ontheroad96j47 > 《待分类》