队列管理和新线程

时间:2012-10-12 10:30:14

标签: c#

在.Net 4.0框架上使用C#,我有一个等待文件系统事件的Windows Forms主线程(唯一一个,直到现在),然后必须对这些事件提供的文件启动一些预定义的处理。

我打算做以下事情:

  • A1。在主进程启动时立即创建一个单独的线程;
  • A2。让主线程放入队列(FIFO)中的文件名 处理;
  • A3。每个n都有一个由计时器触发的新线程 秒;
  • A4。如果有项目,请让新线程读取队列 执行处理,然后让它取消队列项 处理。

因为我以前没有编程线程(我基本上使用Albahari作为我的指南针)但我绝对想要,我有几个问题只是提前发现可能的头痛:

  • Q1。如果主进程只写入并且新进程只取消队列项,我可能会在队列上遇到并发问题吗?换句话说:在这种情况下同步是一个重要问题吗?
  • Q2。我已经看到我可以从头创建一个新线程,或者可以重用现有池中提供的一个线程。在这种情况下,使用池中的线程更安全/更简单吗?
  • Q3。在主进程关闭之前,保持新线程无限期并仅响应计时器是否有任何缺点?

1 个答案:

答案 0 :(得分:2)

如果您的目标是.Net Framework 4,Blocking Collection听起来会解决您的问题;即,当“work”项在队列中可用时(在添加新文件时添加到事件处理程序上的队列中)创建一个新的线程池线程,并在该线程上异步处理它们。

您可以在生产者/消费者队列中使用一个:

E.g:

/// <summary>
/// Producer/consumer queue. Used when a task needs executing, it’s enqueued to ensure order, 
/// allowing the caller to get on with other things. The number of consumers can be defined, 
/// each running on a thread pool task thread. 
/// Adapted from: http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT
/// </summary>
public class ProducerConsumerQueue : IDisposable
{
    private BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();

    public ProducerConsumerQueue(int workerCount)
    {
        // Create and start a separate Task for each consumer:
        for (int i = 0; i < workerCount; i++)
        {
            Task.Factory.StartNew(Consume);
        }
    }

    public void Dispose() 
    { 
        _taskQ.CompleteAdding(); 
    }

    public void EnqueueTask(Action action) 
    { 
        _taskQ.Add(action); 
    }

    private void Consume()
    {
        // This sequence that we’re enumerating will block when no elements
        // are available and will end when CompleteAdding is called.
        // Note: This removes AND returns items from the collection.
        foreach (Action action in _taskQ.GetConsumingEnumerable())
        {
            // Perform task.
            action();
        }
    }
}