0

I'm building a simple Windows Service (basically combining this tutorial with this class).

Now I have a "FROM" directory and two "TO" (TO1, TO2) directories. When I place a file into FROM, it should be copied both to TO1 and TO2. I install the service and I start it in the Service Control Manager where I see it's running. On the first run, it copies the file to TO1 and TO2 and the service is still running after that. Then, when I place another file to FROM (with a different name), nothing happens. And refreshing the services I find that the service stopped.

Why does the service stop? It seems it stops just in the moment when I place the second file.

Here I register the file system watcher:

    // File System Watcher
    var fileSystemWatcher = new FileSystemWatcher();
    fileSystemWatcher.Created += FileSystemWatcher_MoveOnCreate;
    fileSystemWatcher.Path = this.fromPath;
    fileSystemWatcher.EnableRaisingEvents = true;

And here is the event handler:

private void FileSystemWatcher_MoveOnCreate(object sender, FileSystemEventArgs e)
{
    string FROM = Path.Combine(fromPath, e.Name);
    string TO1 = Path.Combine(toPathOne, e.Name);
    string TO2 = Path.Combine(toPathTwo,  e.Name);

    File.Copy(FROM, TO1);
    File.Copy(FROM, TO2)
}
TMOTTM
  • 3,286
  • 6
  • 32
  • 63
  • _sourceFile_ ? Did you mean _FROM_ ? – Steve Aug 26 '19 at 13:16
  • Mind that there is a _limited buffer_ of File System Events. If your copying lasts too long, you might end up losing events. A pattern I've seen and used is to write all events into a queue (fast), so the system's buffer won't kick events. – Fildor Aug 26 '19 at 14:15

1 Answers1

2

If the Windows Service stops there was an unhandled exception in your code somewhere. Try to surround the key point of your code ( maybe the entire body of the function FileSystemWatcher_MoveOnCreate ) with try{}catch(){} and log what's happening. In general you should add log to your windows service is the only way you can understand if things are going on anyway.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
  • Thanks for the hint. In the exception it returns `Exception: System.IO.IOException: The process cannot access the file 'C:\Users\`...\FROM\test-file.txt'` because it is being used by another process. Do I somehow need to release the FROM folder? – TMOTTM Aug 26 '19 at 13:46
  • @TMOTTM well, could be many thing, maybe the process performing the move does not (yet) released the file? some await Task.Delay could help, if it does, maybe adding some retry logic will make the program more robust. – Felice Pollano Aug 26 '19 at 13:49
  • Is there an explicit release method? The files are a couple of kB at most. – TMOTTM Aug 26 '19 at 13:53
  • @TMOTTM I don't think the problem is in your code, but maybe in the other agent performing the move. – Felice Pollano Aug 26 '19 at 13:57
  • 1
    @TOMTOM I'd suggest to also register for Changed Event. Only start Copying when there are no more change events for X time (let's say 1 second). If you copy or move a file into the watched dir, you'll find it is first created (with 0 bytes), then the content written to it. So a collision is not only possible but probable if you only act on Created event without "dead-time". Adding some retry is always a good idea when working with the fsw. (From my experience) – Fildor Aug 26 '19 at 14:00
  • Followed this solution with a for-loop and some delay applied seems to work well. https://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being – TMOTTM Aug 26 '19 at 14:16