Search code examples
windowsmultithreadingwindows-servicesfilesystemwatcher

Having a issue processing multiple files at once in a Windows Service with a FileSystemWatcher


When I try and process more than a couple of files at the same time (they are created and dumped in a folder at the same time), my service dies.

When I wasn't trying to use a thread and had all the processing (where the code in the ProcessFiles method now is) in the Watcher_Created event, at least one file gets through successfully.

When I added the threading (which I'm pretty sure I have to do for this, but am totally unsure of the exact flow and syntax using the threading), I get the following msg in my ProcessFiles method:

System.ArgumentException: Empty path name is not legal. 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)

The above msg occurs on the using line:

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

which is obvious, because the "fullFileName" is an empty string. However, it does get set in the Watcher_Created event:

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

So, I don't understand why the fullFileName variable is an empty string. I know it must have something to do with the threading I'm trying.

My OnStart event looks like this:

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();
        }

Can someone PLEASE inform me how I can use the FileSystemWatcher to process multiple files that are dumped in there at the same time. If I need to use threading, could you please supply how I would use the thread based on the code above?

btw, I'm using the 4.0 framework.


Solution

  • Conceptually something is wrong here. If I understand you correctly, you have two files created in the same folder with short time difference. Then you receive the first event and set the name of ONE file in the global variable fullFileName and you expect that the running thread process this file using the global variable, but in the same time another event Created happens and you change the global variable that the separate thread is processing

    I will try to change you code in this way:

    the OnStart method loose the code that starts the Thread

    the Watcher_Created event will start the thread passing the name of the file that raised the event

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

    the ProcessFiles receive the argument with the name of the file to process...

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