Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#控制台应用程序中实现多线程中的FileSystemWatcher和Timer?_C#_Multithreading_Timer_Console Application_Filesystemwatcher - Fatal编程技术网

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

如何在C#控制台应用程序中实现多线程中的FileSystemWatcher和Timer?,c#,multithreading,timer,console-application,filesystemwatcher,C#,Multithreading,Timer,Console Application,Filesystemwatcher,我需要创建一个C#控制台应用程序,在创建新文件时,该应用程序将解析SFTP目录中的文件。为此,我使用FileCreated事件实现了FileSystemWatcher,该事件将新文件路径排队,并创建一个新线程并解析文件 我在博客中读到,FileSystemWatcher有时可能无法检测到新文件,因为我实现了计时器,它将每1小时启动一次,如果FileSystemWatcher线程处于waitsleep状态,则将读取IMCOMING SFTP文件夹并解析该文件 下面是我为FileSystemWatc

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

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

下面是我为FileSystemWatcher和Timer编写的代码,但它工作不正常,我认为FileSystemWatcher不支持多线程。请帮我找到正确的解决方案

MAIN

   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)
        {

        }
    }
文件系统监视程序代码:

 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);
                    }
                }
            }
        }
     }
public void StartTimer()
{
锁定(锁定对象)
{
if(FileWacherThread==null | | FileWacherThread.ThreadState==ThreadState.WaitSleepJoin)
{
如果(files.Count==0)
{
IEnumerable结果=新列表(Directory.GetFiles(incomingFilePath,“*.CUST”,SearchOption.AllDirectories)),其中(s=>s.Contains(incomingFilePrefix));
foreach(结果中的字符串路径)
{
解析文件(路径);
}
}
}
}
}
要检查的内容

waitHandle
AutoResetEvent
还是
ManualResetEvent
?(从您使用它的方式来看,它应该是一个
AutoResetEvent

如果
shouldStop
true
,则
文件wacherThread
(原文如此)是否在
工作()退出时设置为
null

如何保护对
FileWacherThread
的访问?如果它是从多个线程访问的(为了检查其状态、分配等,那么它也应该使用锁进行保护)

设置事件时,您不必担心
FileWacherThread
的状态。如果要向该线程发送信号,只需设置它(即,构建多线程代码,使发布者不知道/不关心订阅服务器的当前状态)。
目前有一些状态表明,您的
FileWacherThread
可能处于未等待但可能仍需要发出信号的位置。如果您总是设置事件,最糟糕的情况可能是它不必要地循环一次。

什么实际不起作用?顺便说一句,如果您的客户文件很大,您的计时器代码可能也会发现f仍在写入的文件,除非先创建临时文件,并在完成后将其重命名为*.CUST。。