File disappears while multi-threading

T

Tom P.

I am writting a file manager. My network at work is so slow I am now
using a background worker to get the files and make ListViewItems then
add them to the main thread.

I also use a DirectorWatcher to update the file list when something
happens. The DirectoryWatcher in my app sees the change and calls the
background worker to update the files that were affected.

The problem I think I have is when a person is editing a file (a Word
doc specifically). I don't know why but Word apparently creates temp
files and then deletes them right away. So my DirectoryWatcher will
see a change and set off the background worker. The background worker
will try to create the new item but by this time the file is gone and
the background worker gets an exception trying to access it.

I check in the DirectoryWatcher if the change is a delete or create, I
check in the constructor of the ListViewItem if the file exists. Both
come back fine... then I get a FileNotFound exception when I try to
get the file size.

How do I keep up with this? Do I lock the file in the
DirectoryWatcher? But then Word can't clean-up after itself correctly
and we'll end up with a bunch of "~*.tmp" files on the network.

How many times can I check if the file exists before I can trust that
the file does in fact exist? I can't just keep checking every couple
of lines.

Any ideas?

Thanks,
Tom P.
 
P

Pavel Minaev

I am writting a file manager. My network at work is so slow I am now
using a background worker to get the files and make ListViewItems then
add them to the main thread.

I also use a DirectorWatcher to update the file list when something
happens. The DirectoryWatcher in my app sees the change and calls the
background worker to update the files that were affected.

The problem I think I have is when a person is editing a file (a Word
doc specifically). I don't know why but Word apparently creates temp
files and then deletes them right away. So my DirectoryWatcher will
see a change and set off the background worker. The background worker
will try to create the new item but by this time the file is gone and
the background worker gets an exception trying to access it.

I check in the DirectoryWatcher if the change is a delete or create, I
check in the constructor of the ListViewItem if the file exists. Both
come back fine... then I get a FileNotFound exception when I try to
get the file size.

How do I keep up with this? Do I lock the file in the
DirectoryWatcher? But then Word can't clean-up after itself correctly
and we'll end up with a bunch of "~*.tmp" files on the network.

How many times can I check if the file exists before I can trust that
the file does in fact exist? I can't just keep checking every couple
of lines.

It doesn't matter how many times you check, you can always get a race
condition because some other process can do something nasty (like
deleting or moving the file) after your last check, and before you
actually try to use the file. This isn't even specific to your case,
but applies to any code that tries to open a file; e.g. this is
equally unsafe:

if (File.Exists(filename))
{
// assume file exists here
var file = File.OpenRead(filename);
...
}

So, you should always be prepared to get a FileNotFoundException when
opening the file, even immediately after the Exists check. Just handle
this exception correctly (which, in your case, may well be just an
empty block; well, maybe log it), and that's it.
 
T

Tom P.

It doesn't matter how many times you check, you can always get a race
condition because some other process can do something nasty (like
deleting or moving the file) after your last check, and before you
actually try to use the file. This isn't even specific to your case,
but applies to any code that tries to open a file; e.g. this is
equally unsafe:

  if (File.Exists(filename))
  {
    // assume file exists here
    var file = File.OpenRead(filename);
    ...
  }

So, you should always be prepared to get a FileNotFoundException when
opening the file, even immediately after the Exists check. Just handle
this exception correctly (which, in your case, may well be just an
empty block; well, maybe log it), and that's it.


That's what I thought. It's not much multi-threaded as multi-
application. No matter what I do some other application could very
well do whatever it wants to the file regardless of my precautions.

Thanks for the back-up.
Tom P.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top