File IO Race!!

  • Thread starter Thread starter Vai2000
  • Start date Start date
V

Vai2000

Hi All, Here's a situation, I am trying to process some large Files via a
Win Svc using FileMonitor. During the test process I tried copy and pasting
a file in a folder and got an error saying "Process can't access the file
foo.txt as it is being used by another process". I believe the Copy
operation hasn't finished yet though my WinSvc kicked in.....since it got a
FileChange Notification...
How can I avoid the Race Condition?

TIA
 
Hi, Vai2000

please post complete code snippet demonstrating the problem. Otherwise,
chances are you will get generic answers. Like mine:
- could be that you don't close file when finish copy
- could be that you try to access file while it is not yet ready

First one is problem, second one you can avoid by simply waiting for file to
become available

HTH
Alex
 
Unfortunately my module is just too large to post out here.... but here's
the scoop
I call a Delegate on FileCreate event.
FileMonitor.Created += new
System.IO.FileSystemEventHandler(this.FileMonitor_Changed);
Now if you have a large file, the copy operation might not be completed but
the Delegates gets invoked immediately as a file gets created!!! Then the
function in the Delegate tries to access the file... and it throws
exception!!!
How do I know when the file has been completely created so that my worker
classes can access it ?

I was trying to do something like this

retry:
try
{
OperateOnFile(); // FileStram freader = new FileStream(this.fileName,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch(Exception e)
{
Thread.Sleep(15000);
goto retry;
}

But still no Luck!!!


TIA
 
When your delegate gets called, check to see if the file is available.
If not, set a timer for 5 seconds and try again. Keep setting that timer
until the file becomes available... You're probably thinking: "Hey, Michael
Jackson, I know you're the king of pop but do you really know anything about
computers? How can I tell when the file becomes available?" -- well, I'm
glad you asked. I, Michael Jackson, typically try opening the file for
EXCLUSIVE access (see FileStream). If an exception is thrown, the file
hasn't been fully copied yet.

Michael Jackson
 
I tried doing that...please look at the snippet.
retry:
try
{
OperateOnFile(); // FileStram freader = new FileStream(this.fileName,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch(Exception e)
{
Thread.Sleep(15000);
goto retry;
}
 
Hi, Vai2000

-quote-
Common file system operations might raise more than one event. For example,
when a file is moved from one directory to another, several OnChanged and
some OnCreated and OnDeleted events might be raised. Moving a file is a
complex operation that consists of multiple simple operations, therefore
raising multiple events. Likewise, some applications (for example,
anti-virus software) might cause additional file system events that are
detected by FileSystemWatcher
-unquote-

That's what docs are saying. Now, you did not post code which copies file.
Copy it manually and check how long does this take. Your timing should be
close to this. Otherwise - see previous posts.

HTH
Alex
 
Vai2000 said:
Unfortunately my module is just too large to post out here.... but here's
the scoop
I call a Delegate on FileCreate event.
FileMonitor.Created += new
System.IO.FileSystemEventHandler(this.FileMonitor_Changed);
Now if you have a large file, the copy operation might not be completed but
the Delegates gets invoked immediately as a file gets created!!! Then the
function in the Delegate tries to access the file... and it throws
exception!!!
How do I know when the file has been completely created so that my worker
classes can access it ?

I was trying to do something like this

Hi,

you should lock the process and unlock it using a AutoResetEvent... There
are numerous samples on the net using file access and an AutoResetEvent...

retry:
try
{
OperateOnFile(); // FileStram freader = new FileStream(this.fileName,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch(Exception e)
{
Thread.Sleep(15000);

this is not such a good idea...
 
Vai2000 said:
Unfortunately my module is just too large to post out here.... but here's
the scoop
I call a Delegate on FileCreate event.
FileMonitor.Created += new
System.IO.FileSystemEventHandler(this.FileMonitor_Changed);
Now if you have a large file, the copy operation might not be completed but
the Delegates gets invoked immediately as a file gets created!!! Then the
function in the Delegate tries to access the file... and it throws
exception!!!
How do I know when the file has been completely created so that my worker
classes can access it ?

I was trying to do something like this

ps: I have dealt with this before. the solution is simple...

Open the file for exclusive access. If an error is thrown, indeed, pauze
1000 (milliseconds), and loop until the exclusive access is possible.
Be cautious, to avoid an eternal loop, in case the file is not released
properly...
 
Vai2000 said:
I tried doing that...please look at the snippet.
retry:
try
{
OperateOnFile(); // FileStram freader = new FileStream(this.fileName,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

This is wrong... :)

FileStream(this.fileName, FileMode.Open, FileAccess.Read, FileShare.None);
 
File.Copy(src,target,true);

Thats it

AlexS said:
Hi, Vai2000

-quote-
Common file system operations might raise more than one event. For example,
when a file is moved from one directory to another, several OnChanged and
some OnCreated and OnDeleted events might be raised. Moving a file is a
complex operation that consists of multiple simple operations, therefore
raising multiple events. Likewise, some applications (for example,
anti-virus software) might cause additional file system events that are
detected by FileSystemWatcher
-unquote-

That's what docs are saying. Now, you did not post code which copies file.
Copy it manually and check how long does this take. Your timing should be
close to this. Otherwise - see previous posts.

HTH
Alex
 
Back
Top