繁体   English   中英

如何在C#控制台应用程序的多线程中实现FileSystemWatcher和Timer?

[英]How to implement both the FileSystemWatcher and Timer in Multithreading in C# console application?

我需要创建一个C#控制台应用程序,该应用程序将在创建新文件时解析SFTP目录中的文件。 为此,我使用FileCreated事件实现了FileSystemWatcher,该事件排队新文件路径并创建新线程并解析文件。

我在博客中读到,有时FileSystemWatcher可能无法检测到新文件,因为我实现了Timer,该计时器每1小时触发一次,如果FileSystemWatcher线程处于waitsleep状态,则它将读取IMCOMING SFTP文件夹并解析该文件。

以下是我为FileSystemWatcher和Timer编写的代码,但是它无法正常工作,我认为filesystemwatcher不在多线程中。 请帮助我找到正确的解决方案。

主要

   static void Main(string[] args)
    {
        try
        {                
            string path = incomingFilePath;
            if (Directory.Exists(path))
            {
                #region Initiate Timer
                Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));                    
                t.Start((Action)fileProcessor.StartTimer);
                #endregion

                #region FileSystemWatcher
                watcher = new FileSystemWatcher { Path = path, Filter = "*.CUST", IncludeSubdirectories = true };
                watcher.Created += new
                FileSystemEventHandler(watcher_FileCreated);
                watcher.Error += new
                ErrorEventHandler(watcher_OnError);
                watcher.EnableRaisingEvents = true;
                #endregion
            }
        }
        catch (Exception Err)
        {

        }
    }

FILESYSTEMWATCHER代码:

 private static void watcher_FileCreated(object sender, FileSystemEventArgs e)
  {
        if (e.FullPath.ToUpper().Contains("INCOMING"].ToString()))
        {                               
            fileProcessor.EnqueueFile(e.FullPath);
            lock (lockObject)
             {
               files.Enqueue(path);
             }

            if (FileWacherThread == null || shouldStop)
            {
               FileWacherThread = new Thread(new ThreadStart(Work));                
              FileWacherThread.Start();
            }
           // If the thread is waiting then start it
           else if (FileWacherThread.ThreadState == ThreadState.WaitSleepJoin)
           {               
              waitHandle.Set();
           }
        }
    }

  private void Work()
    {
        while (!shouldStop)
        {
            string path = String.Empty;
            lock (lockObject)
            {
                if (files.Count > 0)
                {
                    path = files.Dequeue();
                }
            }

            if (!String.IsNullOrEmpty(path))
            {
                // Process the file                    
                ParseFile(path);
            }
            else
            {
                // If no files are left to process then wait
                waitHandle.WaitOne();
            }
        }
    }

计时器代码

 public void StartTimer()
    {
        lock (lockObject)
        {
           if (FileWacherThread == null || FileWacherThread.ThreadState == ThreadState.WaitSleepJoin)
            {
                if (files.Count == 0)
                {
                    IEnumerable<string> result = new List<string>(Directory.GetFiles(incomingFilePath, "*.CUST", SearchOption.AllDirectories)).Where(s => s.Contains(incomingFilePrefix));
                    foreach (string path in result)
                    {
                        ParseFile(path);
                    }
                }
            }
        }
     }

事情要检查...

waitHandleAutoResetEvent还是ManualResetEvent (从您的使用方式来看,它应该是AutoResetEvent

如果shouldStoptrue ,则在Work()退出时FileWacherThread (sic)是否设置为null ...

您如何保护对FileWacherThread访问? 如果从多个线程访问它(检查它的状态,分配等,那么它也应该用锁保护)。

设置事件时,您不必担心FileWacherThread的状态。 如果要向该线程发出信号,则只需对其进行设置(即,构建多线程代码,以使发布者不知道/不在乎订阅者的当前状态)。 当前,有状态表明FileWacherThread可以处于不等待的位置,但可能仍需要发出信号。 如果始终设置事件,则可能发生的最糟糕的情况是它不必要地循环了一次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM