【问题标题】:Multithreading with Filesystem watcher and/or MSMQ wcf service使用文件系统观察程序和/或 MSMQ wcf 服务的多线程
【发布时间】:2012-02-16 13:06:52
【问题描述】:

我需要创建一个主要负责以下工作的服务:

  1. 在特定文件夹中查看创建的任何新文件。
  2. 如果是,则读取该文件,对其进行处理并将数据保存在 DB 中。

对于上述任务,我正在考虑使用以下任一方法创建多线程服务:

  1. 在主线程中,创建文件系统观察程序的实例,并在创建新文件后立即将该文件添加到线程队列中。会有N个。正在运行的消费者线程应该从队列中获取一个文件并处理它(即第 2 步)。

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

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

谢谢,

【问题讨论】:

  • 是的,服务将在 c# 中

标签: c# multithreading


【解决方案1】:

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

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

编辑:关于FileSystemWatcher的可靠性,MSDN说:

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

因此,这取决于更改发生的频率以及您分配了多少缓冲区。

【讨论】:

  • 首先感谢您的意见。所以理论上单一生产者基本上是 FileSystemWatcher 实例。使用 FileSystemWatcher 有多可靠?有什么想法吗?
  • 生产者实际上是 FileSystemWatcher 工作的线程。至于可靠性,你能澄清一下是什么意思吗?
  • 我的意思是如果同时创建了多个文件,FileSystemWatcher 将如何表现?
  • 感谢您的快速回复。考虑到可靠性问题,我应该使用 FileSystemWatcher 的替代品吗?
  • @user1213831:我不知道任何已知经过可靠测试和推荐的“官方”替代方案。我在各种网站上发现了一些业余项目,但我不知道它们有多好。您是否尝试过在典型场景中测试FileSystemWatcher?可能没那么糟糕。
【解决方案2】:

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

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

另一方面,选项 2 有一个缺点,即 MSMQ 的消息大小限制为每条消息 4 MB(在 Microsoft 博客中解释 here),因此只有一半处理 unicode 字符,而内存中的队列容量更大。

[编辑]

想得久一点,我更喜欢选项2。 在您的评论中,您提到要在文件系统中移动文件。就性能而言,这可能非常代价高昂,如果您在不同分区之间移动文件则更糟。

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

如果在您移动文件时发生任何这些情况,很容易损坏。

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

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

【讨论】:

  • 有趣。对于选项 1,我可以将进程中的文件移动到其他目录,保留该文件,直到消费者线程尚未完成该进程。那么这是否意味着选择选项 1 优于选项 2?虽然我担心使用文件系统观察程序的可靠性来限制缓冲区大小。因为第一个服务也是一个多线程服务,它创建文件并将它们保存到文件夹中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
相关资源
最近更新 更多