使用Filesystem观察器和/或MSMQ wcf服务进行多线程处理

时间:2012-02-16 13:06:52

标签: c# multithreading

我需要创建一个基本上负责以下事项的服务:

  1. 为创建的任何新文件观看特定文件夹。
  2. 如果是,请阅读该文件,对其进行处理并将数据保存在数据库中。
  3. 对于上述任务,我正在考虑使用以下任一方法创建多线程服务:

    1. 在主线程中,创建文件系统观察程序的实例,并在创建新文件后立即在threadQueue中添加该文件。会有N号。运行的消费者线程应该从队列中取出一个文件并对其进行处理(即步骤2)。

    2. 再次在主线程中,创建文件系统观察程序的实例,并在创建新文件后立即读取该文件,并使用wcf MSMQ服务将数据添加到MSMQ。当wcf msmq服务读取消息时,它将负责进一步处理

    3. 在创建多线程服务时,我是新手。所以不确定哪个是最好的选择。请指导我。

      谢谢,

2 个答案:

答案 0 :(得分:0)

首先,让我说你采取了明智的方法来做一个单一的生产者 - 多个消费者模型。在这种情况下,这是最好的方法。

我会选择使用ConcurrentQueue数据结构的选项1,它为您提供了一种以线程安全方式排队任务的简便方法。或者,您可以简单地使用ThreadPool.QueueUserWorkItem方法将工作直接发送到内置线程池,而无需担心明确地管理工作者或队列。

修改:关于FileSystemWatcher的可靠性,MSDN说:

  

Windows操作系统会通知组件文件更改   在FileSystemWatcher创建的缓冲区中。如果有很多   在短时间内发生变化,缓冲区可能会溢出。这导致了   组件忘记跟踪目录中的更改,它只会   提供全面通知。增加缓冲区的大小   InternalBufferSize属性很昂贵,因为它来自   非分页内存,无法换出磁盘,所以保持   缓冲区虽小但足够大,不会错过任何文件更改事件。   要避免缓冲区溢出,请使用NotifyFilter和   IncludeSubdirectories属性,以便您可以过滤掉不需要的更改   通知。

因此,这取决于更改的发生频率以及分配的缓冲区数量。

答案 1 :(得分:0)

我还会考虑您对故障处理的要求以及您发送的文件的大小。 您是否决定选项1或2将取决于规格。

选项2具有优势,通过使用MSMQ,您可以以可恢复的方式保留数据,即使您可能需要重新启动计算机。选项1仅将您的数据存储在内存中,这可能会丢失。

另一方面,选项2有缺点,MSMQ的邮件大小限制为每封邮件4 MB(在Microsoft博客here中说明),因此只有一半使用unicode字符时,内存队列是更大尺寸的功能。

<强> [编辑]

想一想,我宁愿选择 2 。 在您的评论中,您提到要在文件系统中移动文件。这在性能方面可能非常非常昂贵,如果你在不同的部分之间移动文件会更糟。

我在工作中的多个项目中使用了MSQM,并确信它可以很好地满足您的需求。这里的一大优势是MSMQ与事务通信协同工作。这意味着,如果出于某种原因,网络或电力或任何故障发生,您的消息和文件都不会丢失。

如果在您移动文件时发生任何这种情况很容易被破坏。

我唯一抱怨的是文件大小。要解决4 MB的邮件大小限制(请参阅上面添加的链接),我不会将文件内容放入邮件中。代替。我只会发送一个ID或文件路径,以便消费服务可以找到它并在需要时读取它。

这可以使消息和队列大小保持较小,并避免在网络和服务器中使用过多的带宽或内存。