FileSystemWatcher Created() delay

  • Thread starter Thread starter Tushar
  • Start date Start date
T

Tushar

Followup-To: microsoft.public.dotnet.general

Does anyone know when is this event raised, is it:
1) When the file is created but may not have been closed
2) When the file is created AND it has been closed

I am using this control in a Windows-Service I've developed. It works hoever
the problem I'm having is that the file does not seem to be available when I
receive this event. If I include a delay of a few seconds using Sleep(3000)
for example in the event method then the file does become available. It is
as if the application that created the file has not finished with the file
when the event is raised.

Could it be that the Anti-Virus gets hold of it also and checking when I
receive the event. I do not have the rights to stop the AV and therefore I
could not test. If it is not the AV then I see no point if having this API
if one is having to poll for the file to become availabe (to be closed by
the creating application) for it to be processed by the event receiving
application.

Please help.
 
Hi Tushar,

My apologies. After thinking about it, I realized that an event *may* be
raised when the file handle is created. I have scoured the .Net
documentation, and Google to find an answer, but there is no indication in
the .Net docs as to what events exactly the FileSystemWatcher is subscribing
to.

Therefore, I may be in error with my first statement.

So, let me back up a bit and see if I can be more helpful. Since it is not
documented anywhere exactly what event the FileSystemWatcher is monitoring
when a file is created, and we cannot know, perhaps we can look at your
requirements and figure out a workaround.

Your original message read:

So, my first question is, what do you need to do with the file? It certainly
does seem that one of your requirements is that you do something with the
file. Assuming that you do need to access the file, and you state that it
"does not seem to be available," how do you know that it is not available?
That is, are you getting some kind of error? For example, if you are trying
to open the file while it is in use by another process, an exception will be
raised.

If so, I do know (this time!) that there is no way to easily tell if a file
is in use by another process. It is actually less expensive to use a
try/catch to figure this out (it could be done with unmanage API calls, but
again, that's a lot of trouble). So, one solution would be to create a loop
that has a try/catch in it. The try clause would end by exiting the loop.
The catch would put the thread to sleep for a few cycles, and continue the
loop. Something like:

int timeout = 30; // seconds to wait before giving up
while (true)
{
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open,
FileAccess.Read))
{
// do something here
}
break;
}
catch
{
if (--i == 0)
throw new Exception("Unable to open file '" + filePath + "'");
Thread.Sleep(1000);
}
}

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.
 
I get the following...

The process cannot access the file "C:\...\log-Wed.txt" because it is being
used by another process IOException.

Behind the scenes .Net must be using

HANDLE FindFirstChangeNotification(
LPCTSTR lpPathName, // pointer to name of directory to watch
BOOL bWatchSubtree, // flag for monitoring directory or directory tree
DWORD dwNotifyFilter // filter conditions to watch for
);

or

BOOL ReadDirectoryChangesW(
HANDLE hDirectory, // handle to the directory to be watched
LPVOID lpBuffer, // pointer to the buffer to receive the read results
DWORD nBufferLength, // length of lpBuffer
BOOL bWatchSubtree, // flag for monitoring directory or directory tree
DWORD dwNotifyFilter, // filter conditions to watch for
LPDWORD lpBytesReturned, // number of bytes returned
LPOVERLAPPED lpOverlapped, // pointer to structure needed for overlapped
I/O
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // pointer to
completion routine
);

Please help

Hi Tushar,

My apologies. After thinking about it, I realized that an event *may* be
raised when the file handle is created. I have scoured the .Net
documentation, and Google to find an answer, but there is no indication in
the .Net docs as to what events exactly the FileSystemWatcher is subscribing
to.

Therefore, I may be in error with my first statement.

So, let me back up a bit and see if I can be more helpful. Since it is not
documented anywhere exactly what event the FileSystemWatcher is monitoring
when a file is created, and we cannot know, perhaps we can look at your
requirements and figure out a workaround.

Your original message read:

So, my first question is, what do you need to do with the file? It certainly
does seem that one of your requirements is that you do something with the
file. Assuming that you do need to access the file, and you state that it
"does not seem to be available," how do you know that it is not available?
That is, are you getting some kind of error? For example, if you are trying
to open the file while it is in use by another process, an exception will be
raised.

If so, I do know (this time!) that there is no way to easily tell if a file
is in use by another process. It is actually less expensive to use a
try/catch to figure this out (it could be done with unmanage API calls, but
again, that's a lot of trouble). So, one solution would be to create a loop
that has a try/catch in it. The try clause would end by exiting the loop.
The catch would put the thread to sleep for a few cycles, and continue the
loop. Something like:

int timeout = 30; // seconds to wait before giving up
while (true)
{
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open,
FileAccess.Read))
{
// do something here
}
break;
}
catch
{
if (--i == 0)
throw new Exception("Unable to open file '" + filePath + "'");
Thread.Sleep(1000);
}
}

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.
 
Back
Top