【发布时间】:2013-06-25 14:12:02
【问题描述】:
同时牢记:
- 我正在使用一个阻塞队列,它会一直等待直到向其中添加某些内容
- 我可能会收到两次 FileSystemWatcher 事件
更新代码:
{
FileProcessingManager processingManager = new FileProcessingManager();
processingManager.RegisterProcessor(new ExcelFileProcessor());
processingManager.RegisterProcessor(new PdfFileProcessor());
processingManager.Completed += new ProcessingCompletedHandler(ProcessingCompletedHandler);
processingManager.Completed += new ProcessingCompletedHandler(LogFileStatus);
while (true)
{
try
{
var jobData = (JobData)fileMonitor.FileQueue.Dequeue();
if (jobData == null)
break;
_pool.WaitOne();
Application.Log(String.Format("{0}:{1}", DateTime.Now.ToString(CultureInfo.InvariantCulture), "Thread launched"));
Task.Factory.StartNew(() => processingManager.Process(jobData));
}
catch (Exception e)
{
Application.Log(String.Format("{0}:{1}", DateTime.Now.ToString(CultureInfo.InvariantCulture), e.Message));
}
}
}
考虑到两个相同的字符串路径可能被添加到阻塞队列中的可能性,您对使代码多线程有什么建议?我留下了可能发生这种情况的可能性,在这种情况下..文件将被处理两次,问题是有时我得到两次,有时没有,这真的很尴尬,如果您对此有建议,请告诉。
空值检查是为了退出循环,我特意在线程循环外加一个空值来判断它是否停止。
【问题讨论】:
-
您可以对队列进行重复数据删除吗?你期待什么样的路径?如果您正在处理多个目录中的所有文件,那么您可以为每个目录执行一个线程。
-
收到警报后,可以先将文件移动到子文件夹吗?如果移动成功,则将其添加到队列中。由于一个文件只能从 A 移动到 B 一次,这应该可以防止重复。
-
文件路径,在单个目录中,仅此而已。我不知道重复数据删除是否对我有帮助,因为当第二个事件到达时,第一个通知可能会从队列中弹出,因此第二个通知在当时队列中是唯一的
-
@mbeckish 你的想法很有趣,但是考虑到例如非常大的文件,这不会增加很多开销吗?
-
@A.K - 你可以做一些其他的原子操作,比如向数据库表中添加一条记录,创建一个空的“锁定”文件,等等。
标签: c# multithreading design-patterns