0

同时牢记:

  • 我正在使用一个阻塞队列,它一直等待直到添加一些东西
  • 我可能会收到两次 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));
            }
        }
    }

考虑到两个相同的字符串路径可能被添加到阻塞队列中的可能性,你对使代码多线程有什么建议?我已经留下了可能发生这种情况的可能性,在这种情况下..文件将被处理两次,问题是有时我得到两次,有时没有,这真的很尴尬,如果您对此有建议,请告诉。

空值检查是为了退出循环,我故意从线程循环外部添加一个空值来确定它停止。

4

1 回答 1

1

对于多线程...我可能会在您的 FileProcessingManager 中添加一个“已完成”事件并注册它。该事件的一个参数将是您当前拥有的“布尔”返回值。然后在那个事件处理程序中,我会检查布尔值并重新排队文件。请注意,您必须保留对 FileMonitorManager 的引用。因此,我将这个 ThreadProc 方法放在一个类中,在该类中,您将 FileMonitorManager 和 FileProcessingManager 实例保存在一个属性中。

为了去重,在 ThreadProc 中,我会在 while 循环之外创建一个列表。然后在while循环中,在处理文件之前,锁定该列表,检查字符串是否已经在其中,如果没有,将字符串添加到列表并处理文件,如果是,则跳过处理。

显然,这是基于围绕您的方法的少量信息,但无论如何我的 2 美分。

粗略的代码,来自记事本:

private static FileMonitorManager fileMon = null;
private static FileProcessingManager processingManager = new FileProcessingManager();

private static void ThreadProc(object param)
{
    processingManager.RegisterProcessor(new ExcelFileProcessor());
    processingManager.RegisterProcessor(new PdfFileProcessor());
    processingManager.Completed += ProcessingCompletedHandler;
    var procList = new List<string>();

    while (true)
    {
        try
        {
            var path = (string)fileMon.FileQueue.Dequeue();
            if (path == null)
                break;

            bool processThis = false;
            lock(procList)
            {
                if(!procList.Contains(path))
                {
                    processThis = true;
                    procList.Add(path);
                }
            }
            if(processThis)
            {
                Thread t = new Thread (new ParameterizedThreadStart(processingManager.Process));
                t.Start (path);
            }
        }
        catch (System.Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

private static void ProcessingCompletedHandler(bool status, string path)
{
    if (!status)
    {
        fileMon.FileQueue.Enqueue(path);
        Console.WriteLine("\n\nError on file: " + path);
    }
    else
        Console.WriteLine("\n\nSucces on file: " + path);
}
于 2013-06-25T14:25:36.907 回答