线程职位列表管理

时间:2016-05-31 09:51:36

标签: c# multithreading list concurrency

我在C#工作。

我现在一直在寻找年龄,似乎找不到适合我情况的任何东西。这是我真正问题的摘要,因为我解释起来太复杂了。

我有一个工作线程,在每次打印后打印一个列表中的整数,延迟时间很短,当打印整数时,它会从列表中删除,当列表为空时,它应该等待更多的添加。 现在我需要能够 - 在任何时候 - 将我选择的数量添加到此列表的前面。但是我遇到了并发问题。因为他们显然不能同时在列表上工作。我一直在关注生产者 - 消费者模型,但我不能让它适应这个项目。

你知道任何适合这种情况的例子吗?

2 个答案:

答案 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();
    }
}