Windows Service File Listener

  • Thread starter Thread starter Vinny
  • Start date Start date
V

Vinny

Hey all. I'm now attributing the problem I'm having to something
incredibly simple, to which I must be overlooking.

I created a Windows Service application that listens for files. The
file paths are in a config file. I then write information out to an
event log so as files are dropped into their location, I receive
information. Lastly, I wish to delete the file(s) once they are dropped
.. This is where I'm getting the awkward behavior. I get the following
exception (sometimes):

"The process cannot access the file "C:\temp\test1.txt" because it is
being used by another process."
The sometimes occurence tells me that I am either having a garbage
collection or threading problem. Here is the code I use to add the file
listener for each file:

foreach(XmlNode XNode in Config.DocumentElement.SelectNodes("folder"))
{
fileSystemWatcher = new System.IO.FileSystemWatcher();

((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher)).BeginInit();
fileSystemWatcher.Path =
Path.GetDirectoryName(XNode.Attributes["name"].Value.ToString());
fileSystemWatcher.Filter =
Path.GetFileName(XNode.Attributes["name"].Value.ToString());
this.fileSystemWatcher.EnableRaisingEvents = true;
this.fileSystemWatcher.Created += new
System.IO.FileSystemEventHandler(this.fileSystemWatcher_Created);

((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher)).EndInit();
eventLog1.WriteEntry("Adding File Watcher for " +
XNode.Attributes["name"].Value.ToString());
}

this code does work correctly, as the Created event does fire anytime I
add one of the files specified in the app.config file to the directory.

This is the Created event code:

private void fileSystemWatcher_Created(object sender,
System.IO.FileSystemEventArgs e)
{
eventLog1.WriteEntry(e.FullPath.ToString() + " has been delivered");
try
{
File.Delete(e.FullPath);
}
catch (Exception ex)
{
eventLog1.WriteEntry(ex.Message);
}
}
I got desperate and tried to invoke some garbage collection, but the
behavior did not change:

byte[] bytes = new byte[100*(1<<20)];
for(int i=0; i<bytes.Length; i++)
bytes = 0;
bytes = null;
GC.Collect();
Thread.Sleep(2000);

Anyone out there with any ideas, I'd really appeciate it. Thanks
all!!!!
 
Vinny said:
Hey all. I'm now attributing the problem I'm having to something
incredibly simple, to which I must be overlooking.

I created a Windows Service application that listens for files. The
file paths are in a config file. I then write information out to an
event log so as files are dropped into their location, I receive
information. Lastly, I wish to delete the file(s) once they are dropped
. This is where I'm getting the awkward behavior. I get the following
exception (sometimes):

<snip>

The problem is just that you're getting told when the file is being
created, not when whatever's creating it has finished writing to it.

You could loop round for a few times, sleeping between attempts, until
you can delete it.
 
Thanks for the quick response. It turns out that the Changed event as
opposed to the Created event provides the consistency I was looking
for. Also, adding a short duration sleep command (100 ms) allowed the
service (which is multi-threaded) to relinquish control to the worker
threads. Unfortunately, using the Changed event , triggers multiple
times as the file is being written to the directory, which results in
multiple writes to the event log for a single file. Is there any way to
check when a file has completed writing after being placed in a folder?
 
Hi,

No really, you can do one of several things:
1- If you control the file's generator you can opt to create a "flag" file
with the same name that the output file with a different extension, and
"watch" this flag file instead of the content file itself.
2- use a timespan and ignore the events that occur before the timespan
elapse, this would prevent to process two close events.


Or a combination of both.


Cheers,
 
Back
Top