我正在开始开发一个Windows服务,并希望在进行深入介绍之前先咨询stackoverflow的脑力劳动,以了解处理它的最佳方法。
这将是我的第一个Windows服务,我对线程并不熟悉,这就是我假设的建议(但我很想学习!)。
该服务将具有以下高级别功能:
即使在这个高级别,我可以预见的问题是,文件到外部主机的HTTP POST可能需要很长时间。
有哪些设计选项可以最好地处理Windows服务的长期运行方面?我是否应该根据使用Windows服务作为此解决方案的实现?我应该调查一个独立的应用程序吗?
提前感谢溢出!
答案 0 :(得分:3)
Windows服务IMO并不是一个坏主意,特别是因为您希望它不断尝试检测文件夹中的文件。 HTTP POST限制很重要,但您知道它将占用的时间和资源。我认为你最关心的是排队和资源管理。您需要将每个传输转换为BackgroundWorker进程,以便可以独立完成多个文件,但您还需要一个可以限制可以旋转的BackgroundWorker对象数量的管理类。否则你会遇到内存管理问题,网络堵塞,谁知道还有什么。
您应该关注文件夹中出现的文件的最差/最佳情况。同时出现的最大文件数是多少,文件的最大大小是什么,当文件夹开始“备份”时会发生什么,因为HTTP POST没有足够快地将它们传送到目的地。目标主机无法访问时会发生什么?当系统重新启动“中间交付”时会发生什么?是否有确定文件传递优先级的来源?是否存在文件传递必须中断或交易逆转的情况?
我认为Windows服务是正确的选择,与FileSystemWatcher结合使用。请注意您的资源使用情况。
答案 1 :(得分:1)
Windows服务绝对是您的选择。在启动服务的方法中,您必须创建必要的FileSystemWatcher
实例。
创建新文件时,将触发事件,您必须及时处理这些事件。事件在线程池的线程上执行,如果事件处理程序没有立即返回,则未来的事件可能会丢失。这意味着您必须排队某种形式的任务。您可以使用.NET 4中的新版Task Parallel Library,BackgroundWorker class
,ThreadPool.QueueUserWorkItem method
或类似内容。通常,这些技术都使用大小有限的.NET线程池来限制服务将使用的系统资源量。
每次创建新文件时对新任务进行排队将允许任务并行执行。如果您只希望一次执行单个任务,则必须将任务放入队列中。您可以使用易失性内存中队列,但另一种方法是使用持久和事务性MSMQ队列。如果文件足够小以存储在队列中,则可以以事务方式读取,排队和删除文件。然后,另一个任务必须将队列中的文件出列并处理它们。任何失败都会回滚事务并将文件保留在队列中。这将解决尝试将文件系统用作事务数据库的问题。
如果您的文件快速到达,则必须处理错过FileSystemWatcher
的事件的情况。定期(即每分钟一次)服务扫描文件系统的方法可能会更好地为您服务。这可以使用计时器类(System.Timers.Timer
class或System.Threading.Timer
class)来完成。
在启动期间,您的服务必须枚举现有但未经处理的文件并将其排队等待处理。
如果您的服务必须非常可靠,您必须考虑所有可能的故障情况,例如意外终止服务或磁盘已满。
答案 2 :(得分:0)
好吧,如果我理解你的话,你想要达到的目标并不复杂。
我会选择Windows服务和FileSystemWatcher。
您需要做的线程不多。我唯一要解决的是文件上传,这可以通过BackgroundWorker轻松完成。通过线程化,您可以异步上传多个文件。
如果您需要更多帮助,请与我们联系。
答案 3 :(得分:0)
Windows服务是可行的方法。
我没有预见到任何问题,因为我之前几乎完全相同,除了我连接到数据库而不是http服务,并且没有任何问题。
您不需要多线程,特别是因为您一次只发布一个文件。
如果您有一个应用程序来监控您的服务,并在发生故障时发送电子邮件/短信,那将非常有用。
答案 4 :(得分:0)
我最近使用SmartThreadPool来管理Windows服务应用程序中的并发FTP上传。
Windows服务使用Quartz.Net计划来启动FTP上传作业,但我需要在很短的时间内完成200次上传。每个单独上传需要15分钟,但所有200个需要在2小时内完成。
当Quartz触发其预定事件时,我在SmartThreadPool中填充了代表每个FTP端点的200个类实例,让SmartThreadPool管理资源使用情况。 (当我们的任务由Quartz运行需要很长时间,很长一分钟或更长时间时,我们遇到了Quartz触发器丢失的问题)
我发现我很容易扩展到60个线程(我去过的最高线程),几乎是线性并发。也就是说,连续200次上传几乎需要50个小时才能完成,让SmartThreadPool最多使用50个线程将整个过程缩短到接近1个小时。
这种方法对我们来说效果非常好,我会推荐它。
答案 5 :(得分:0)
我同意其他人的意见。使用Windows服务完成此任务非常有意义。
我唯一的指导是避免使用BackgroundWorker
进行线程,因为您在Windows服务中执行此操作。 BackgroundWorker
类旨在提供有关线程操作进度的反馈。除非您计划让前端应用程序从Windows服务接收反馈,然后将该信息提供给用户(例如,使用进度条),否则BackgroundWorker
对象对您所需的内容来说太过分了。我建议使用ThreadPool
或Thread
类,具体取决于您的具体情况。有关选择哪些方面的指导,请参阅指南here。
答案 6 :(得分:0)
FileSystemWatcher的
此系统的一个大问题是,当文件系统最初在目录中创建一个条目时,事件通常会开始触发,并且事件将在写入文件时继续触发。但是,一般的期望是文件系统观察程序将在文件完全写入目录后触发。即使filesystemwatcher已经开始触发事件,这也会导致尚未完成传输到目录的大文件出现问题。
一个强大的解决方案必须使用某种类型的测试来包装filesystemwatcher事件,该文件已完成写入。我目前没有任何方便的参考资料,但有很多解决方案可以解决这个问题。