开发者

Waiting for FileSystemWatcher event to fire before completing a thread

This is a bit convoluted but I will try to explain as best as possible.

I'm using the FileSystemWatcher with a notify filter of

toFileWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName;

I have a .Created method and a .Changed method.

When the .Created event fires it runs through some preliminary checks using the file name supplied from the watcher, checking to see if the file has been seen yet, getting a destination folder, and returning validation information.

I'm running into an issue where the validation is at the end of the .Created method and it accesses the file to do so开发者_如何转开发me validation before copying it on to its destination. When I get to this point, if the file is large and still in the process of copying from its source, it returns an io "file is already in use" error.

what I want to do is finish all of the preliminary code and then I want the thread to "hang" until the .Changed method for the file fires indicating that the file is done since i'm only catching the changes to the last access filter.


Use can use a ManualResetEvent. The Created method can do its work and then wait for the Changed event signals that the Created method can continue.


I would setup a separate thread using the producer-consumer pattern that watches for items to appear in a queue. These items will represent the file changes and include information like the path to the file and what kind of change occurred. Your FileSystemWatcher event handlers will just post items to the queue and let the consumer thread dequeue and process the information. This will decouple the processing you require from the file system notification events where it will be easier to avoid to the "file in use" problems.


This problem is normal, you cannot typically open the file while the other process is busy writing to it. You'll need to wait, you cannot predict when it will be done. Add the path to the file to a list and use a timer to empty that list, periodically retrying the operation. Careful with the logic, you're using threads so you'll need to protect the list with a lock.


Please note that NotifyFilters.LastAccess does not mean that you will know when the other process has finished with the file. It simply means that you get notified when the Last Access Time of the file has changed.

I typically go with Brian Gideon's producer-consumer pattern. This also makes it easy to filter out the (typical) multiple Changed events that the FileSystemWatcher happily hands out.

The only way to be (almost) sure that the other process has finished with the file is trying to obtain an exclusive lock on it. This will not always be enough, though. I've seen an FTP-server that closed and reopened the file for each block it wrote ;-)

Please also note that the FileSystemWatcher does have an internal buffer in which it buffers the File Notifications it gets from Windows, but that this buffer may overflow if a lot happens. This is again a reason for creating a producer-consumer.

I typically amend this by creating a routine that can manually scan the watched directories and then run it once in a while. Yeah, polling ;-)

Having this routine is also nice when starting your application. Files may have arrived while it was down!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜