我正在使用C#。
我已经寻找了很多年了,似乎找不到任何适合我的情况。这是我真正问题的摘要,因为它对我来说太复杂了,无法解释。
我有一个工作线程,每次打印后都会有很小的延迟从列表中打印整数,当打印整数时,它会从列表中删除,当列表为空时,它应该等待添加更多。现在我需要能够 - 在任何时候 - 将我选择的一些添加到此列表的前面。但是我遇到了并发问题。因为他们显然不能同时在名单上工作。我一直在研究生产者-消费者模式,但我无法让它适合这个项目。
你知道有什么适合这种情况的例子吗?
这些解决方案呢:
class Example
{
private readonly ManualResetEventSlim _hasNewData;
private readonly ConcurrentQueue<int> _queue;
private readonly CancellationTokenSource _stopConsumers;
private readonly ManualResetEvent _waitForStopping;
private Task _printTask;
public Example()
{
_hasNewData = new ManualResetEventSlim(false);
_queue = new ConcurrentQueue<int>();
_stopConsumers = new CancellationTokenSource();
_waitForStopping = new ManualResetEvent(false);
}
public void Start()
{
_printTask = Task.Factory.StartNew(() => PrintMethod());
}
public void Add(int v)
{
_hasNewData.Set();
_queue.Enqueue(v);
}
public void Stop()
{
_stopConsumers.Cancel();
_waitForStopping.WaitOne();
}
private void PrintMethod()
{
while (!_stopConsumers.IsCancellationRequested)
{
_hasNewData.Wait();
int v;
while(_queue.TryDequeue(out v))
{
Console.WriteLine("Dequed: {0}", v);
}
}
_waitForStopping.Set();
}
}
以这种方式使用:
Example e = new Example();
e.Start();
int k = 0;
while (true)
{
e.Add(k++);
Console.ReadLine();
}
这非常有效。
class Program
{
static void Main(string[] args)
{
int[] ints = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110,120,130,140,150 };
Example e = new Example();
e.AddRange(ints);
e.Start();
int k = 0;
while (true)
{
int input = int.Parse(Console.ReadLine());
e.Add(input);
}
}
}
class Example
{
private readonly ManualResetEventSlim _hasNewData;
private readonly ConcurrentStack<int> _queue;
private readonly CancellationTokenSource _stopConsumers;
private readonly ManualResetEvent _waitForStopping;
private Task _printTask;
public Example()
{
_hasNewData = new ManualResetEventSlim(false);
_queue = new ConcurrentStack<int>();
_stopConsumers = new CancellationTokenSource();
_waitForStopping = new ManualResetEvent(false);
}
public void Start()
{
_printTask = Task.Factory.StartNew(() => PrintMethod());
}
public void AddRange(int[] ints)
{
_hasNewData.Set();
_queue.PushRange(ints);
}
public void Add(int v)
{
_hasNewData.Set();
_queue.Push(v);
}
public void Stop()
{
_stopConsumers.Cancel();
_waitForStopping.WaitOne();
}
private void PrintMethod()
{
while (!_stopConsumers.IsCancellationRequested)
{
_hasNewData.Wait();
int v;
while (_queue.TryPop(out v))
{
Console.WriteLine("Dequed: {0}", v);
Thread.Sleep(500);
}
}
_waitForStopping.Set();
}
}