C# 队列管理和新线程

C# 队列管理和新线程,c#,C#,使用.NET4.0框架上的C#,我有一个Windows窗体主线程(迄今为止唯一的一个)等待文件系统事件,然后必须对这些事件提供的文件启动一些预定义的处理 我计划做以下工作: A1。在主进程启动时立即创建一个单独的线程 A2。让主线程将要访问的文件名放入队列(FIFO) 加工 A3。让新线程每n秒由计时器触发一次 秒 A4。如果有项目,让新线程读取队列 要执行该处理,请让它仅取消队列项目 已处理 因为我以前从未编程过线程(我基本上使用Albahari作为我的指南针),但我确实想,我有几个问题只

使用.NET4.0框架上的C#,我有一个Windows窗体主线程(迄今为止唯一的一个)等待文件系统事件,然后必须对这些事件提供的文件启动一些预定义的处理

我计划做以下工作:

  • A1。在主进程启动时立即创建一个单独的线程
  • A2。让主线程将要访问的文件名放入队列(FIFO) 加工
  • A3。让新线程每n秒由计时器触发一次 秒
  • A4。如果有项目,让新线程读取队列 要执行该处理,请让它仅取消队列项目 已处理
因为我以前从未编程过线程(我基本上使用Albahari作为我的指南针),但我确实想,我有几个问题只是为了提前发现可能的严重头痛:

  • 问题1。如果主进程只写,而新进程只取消队列项,我是否会在队列上引发并发问题?换句话说:在这种情况下,同步是一个重要的问题吗
  • 问题2。我已经看到,我可以从头开始创建一个新线程,或者可以重用现有池中可用的一个线程。在此上下文中使用池中的线程更安全/更简单
  • 第三季度。在主进程关闭之前,让新线程无限期地保持活动状态并只对计时器作出响应是否有任何缺点

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

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

例如:

//
///生产者/消费者队列。当任务需要执行时使用,它排队以确保顺序,
///允许来电者继续处理其他事情。消费者的数量可以定义,
///每个线程在一个线程池任务线程上运行。
///改编自:http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT
/// 
公共类ProducerConsumerQueue:IDisposable
{
私有BlockingCollection_taskQ=新BlockingCollection();
public ProducerConsumerQueue(int workerCount)
{
//为每个使用者创建并启动单独的任务:
对于(int i=0;i
/// <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();
        }
    }
}