【问题标题】:Having a issue processing multiple files at once in a Windows Service with a FileSystemWatcher使用 FileSystemWatcher 在 Windows 服务中一次处理多个文件时出现问题
【发布时间】:2012-12-26 22:59:54
【问题描述】:

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

当我没有尝试使用线程并且在 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)

上面的消息出现在 using 行:

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 框架。

【问题讨论】:

    标签: windows multithreading windows-services filesystemwatcher


    【解决方案1】:

    从概念上讲,这里有问题。如果我理解正确,您在同一个文件夹中创建了两个时间差很短的文件。然后您收到第一个事件并在全局变量 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, ....))
          .....
    }
    

    【讨论】:

    • 史蒂夫,非常感谢您的回复……我按照您的建议格式化了代码。但是,如果我在 t.Start 上包含一个参数(如上所述),“Thread t = new Thread(new ThreadStart(ProcessFiles))”会给我一个设计时编译错误“ProcessFiles 没有重载匹配委托” System.Threading.ThreadStart',这意味着我不能将任何参数传递给它。我知道在 t.Start 中,有一个包含参数的选项。我们在这里遗漏了什么吗?
    • 抱歉,复制/粘贴失败了。检查更新。无需使用ThreadStart,只传递方法名,编译器会推断出合适的委托(ParametrizedThreadStart)
    • 如果我尝试像你一样运行它,服务只会在 t.Start 方法上停止,并出现以下错误:“ex = {”线程是使用不接受的 ThreadStart 委托创建的参数。"}"
    • 方法名刚刚被传递:"Thread t = new Thread(new ThreadStart(ProcessFiles));"您能否更新您之前发送的代码语法,以便我与您所说的保持同步?非常感谢您的帮助....
    • 但是您是否更改了 ProcessFile 方法以接收参数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多