示例
Program.cs
using System.Collections.Concurrent;
using System.Data;
namespace WaitPulseExample
{
internal class Program
{
static void Main(string[] args)
{
Producer producer = new Producer();
Consumer consumer = new Consumer();
ThreadStart ts1 = new ThreadStart(producer.Produce);
ThreadStart ts2 = new ThreadStart(consumer.Consume);
Thread producerThread = new Thread(ts1) { Name = "Producer Thread" };
Thread consumerTherad = new Thread(ts2) { Name = "Consumer Thread" };
producerThread.Start();
consumerTherad.Start();
producerThread.Join();
consumerTherad.Join();
Console.ReadKey();
}
}
static class Shared
{
public static ConcurrentQueue<int> Buffer = new ConcurrentQueue<int>();
public const int BufferCapacity = 5;
public const int MaxNumber = 1000;
public static ManualResetEvent ProducerEvent = new ManualResetEvent(false);
public static ManualResetEvent ConsumerEvent = new ManualResetEvent(false);
public static void Print()
{
Console.WriteLine("Buffer: ");
foreach (int i in Buffer)
{
Console.Write($"{i}, ");
}
Console.WriteLine();
}
}
class Producer
{
public void Produce()
{
Console.WriteLine($"Producer: Generating Data.");
for (int i = 1; i <= Shared.MaxNumber; i++)
{
//Thread.Sleep(1000);
if (Shared.Buffer.Count == Shared.BufferCapacity)
{
Console.WriteLine("Buffer is full. Waiting for signal from consumer.");
Shared.ProducerEvent.Reset(); // unsignaled
Shared.ConsumerEvent.Set();
}
Shared.ProducerEvent.WaitOne();
Shared.Buffer.Enqueue(i);
Console.WriteLine($"Producer produced: {i}");
Shared.Print();
Shared.ConsumerEvent.Set();
}
Console.WriteLine($"Producer: Completed.");
}
}
class Consumer
{
public void Consume()
{
Console.WriteLine($"Consumer: Consuming Data.");
for (int i = 0; i < Shared.MaxNumber; i++)
{
if (Shared.Buffer.Count <= 0)
{
Console.WriteLine("Buffer is empty. Waiting for signal from producer.");
Shared.ConsumerEvent.Reset(); //Set the consumer event as "unsignaled"
Shared.ProducerEvent.Set();
}
Shared.ConsumerEvent.WaitOne();
Console.WriteLine("Consumer: Processing Data.");
//Thread.Sleep(2500);
bool isSuccess = Shared.Buffer.TryDequeue(out int value);
if (isSuccess)
{
Console.WriteLine($"Consumer consumed: {value}");
}
else
{
Console.WriteLine("Failed to read from quene.");
}
//Signal the producer that there is a space in the buffer
Shared.ProducerEvent.Set();
}
Console.WriteLine($"Consumer: Completed.");
}
}
}