使用FileSystemWatcher在Windows服务中一次处理多个文件时出现问题

时间:2012-12-26 22:59:54

标签: windows multithreading windows-services filesystemwatcher

当我尝试同时处理多个文件时(它们同时被创建并转储到一个文件夹中),我的服务就会消失。

当我没有尝试使用线程并且在Watcher_Created事件中进行了所有处理(现在ProcessFiles方法中的代码)时,至少有一个文件成功通过。

当我添加线程时(我非常肯定我必须为此做,但我完全不确定使用线程的确切流程和语法),我在我的ProcessFiles方法中得到以下消息:

System.ArgumentException:空路径名不合法。    at System.IO.FileStream.Init(String path,FileMode mode,FileAccess access,Int32 rights,Boolean useRights,FileShare share,Int32 bufferSize,FileOptions options,SECURITY_ATTRIBUTES secAttrs,String msgPath,Boolean bFromProxy,Boolean useLongPath)

上述消息发生在使用行:

private static void ProcessFiles()
        {
            try
            {
Thread.Sleep(500);

GetCruiseLineShipName(fullFileName, ref cruiseLine, ref shipName);
using (StreamReader sr = new StreamReader(File.Open(fullFileName, FileMode.Open, FileAccess.Read, FileShare.Read)))

这很明显,因为“fullFileName”是一个空字符串。但是,它确实在Watcher_Created事件中设置:

private static void Watcher_Created(object sender, FileSystemEventArgs e)
        {
            fullFileName = e.FullPath;
        }

所以,我不明白为什么fullFileName变量是一个空字符串。我知道它必须与我正在尝试的线程有关。

我的OnStart事件如下所示:

protected override void OnStart(string[] args)
        {
            FileSystemWatcher Watcher = new FileSystemWatcher(@"C:\DropOff_FTP\MIS");

            Watcher.EnableRaisingEvents = true;
            Watcher.Created += new FileSystemEventHandler(Watcher_Created);
            Watcher.Filter = "*.txt";
            Watcher.IncludeSubdirectories = false;
            Watcher.InternalBufferSize = 64;

            Thread t = new Thread(new ThreadStart(ProcessFiles));
            t.Start();
        }

有人可以告诉我如何使用FileSystemWatcher处理同时转储的多个文件。如果我需要使用线程,你能否根据上面的代码提供我将如何使用线程?

不过,我正在使用4.0框架。

1 个答案:

答案 0 :(得分:2)

概念上这里有些不对劲。如果我理解正确,您在同一文件夹中创建了两个文件,时差很短。然后你收到第一个事件并在全局变量fullFileName中设置ONE文件的名称,并且你希望正在运行的线程使用全局变量处理这个文件,但是同时另一个事件Created发生并且你改变了全局变量单独的线程正在处理

我将尝试以这种方式更改您的代码:

OnStart方法松开了启动线程的代码

Watcher_Created事件将启动线程传递引发事件的文件的名称

.....
Thread t = new Thread(ProcessFiles);
t.Start(e.FullPath);
.....

ProcessFiles接收带有要处理的文件名称的参数...

public void ProcessFiles(object argument) 
{
      string fullFileName = (string)argument;
      GetCruiseLineShipName(fullFileName, ref cruiseLine, ref shipName);
      using (StreamReader sr = new StreamReader(File.Open(fullFileName, ....))
      .....
}