我在C#工作。
我现在一直在寻找年龄,似乎找不到适合我情况的任何东西。这是我真正问题的摘要,因为我解释起来太复杂了。
我有一个工作线程,在每次打印后打印一个列表中的整数,延迟时间很短,当打印整数时,它会从列表中删除,当列表为空时,它应该等待更多的添加。 现在我需要能够 - 在任何时候 - 将我选择的数量添加到此列表的前面。但是我遇到了并发问题。因为他们显然不能同时在列表上工作。我一直在关注生产者 - 消费者模型,但我不能让它适应这个项目。
你知道任何适合这种情况的例子吗?
答案 0 :(得分:0)
这些解决方案如何:
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();
}
答案 1 :(得分:0)
这非常出色。
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();
}
}