In .NET, you can use the FileSystemWatcher to notify when a particular event occurs in the filesystem, such as the renaming of a particular file or directory, the increasing or decreasing of the size of a file, the user deleting a file or directory, the creation of a file or directory, or even the changing of a file or directory’s attribute(s).
The WaitForChanged method of the FileSystemWatcher class can be called to wait synchronously for an event notification. This is illustrated in the following method, which waits for an action¡ªmore specifically, the action of creating the Backup.zip file somewhere on the C:\ drive¡ªto be performed before proceeding on to the next line of code, which is the WriteLine statement. Finally, we ask the ThreadPool to use a thread to go create the file in question using the PauseAndCreateFile method, so that the FileSystemWatcher can detect the file creation:
public void WaitForZipCreation(string path, string fileName) { FileSystemWatcher fsw = null; try { fsw = new FileSystemWatcher(); string[] data = new string[] {path,fileName}; fsw.Path = path; fsw.Filter = fileName; fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // Run the code to generate the file we are looking for // Normally you wouldn't do this as another source is creating // this file if (ThreadPool.QueueUserWorkItem(new WaitCallback(PauseAndCreateFile), data)) { // block waiting for change WaitForChangedResult result = fsw.WaitForChanged(WatcherChangeTypes.Created); Console.WriteLine("{0} created at {1}.", result.Name, path); } } catch(Exception e) { Console.WriteLine(e.ToString()); } // clean it up File.Delete(fileName); if (fsw != null) fsw.Dispose(); }
The code for PauseAndCreateFile is listed here. It is in the form of a WaitCallback to be used as an argument to QueueUserWorkItem on the Thread class. QueueUserWorkItem will run PauseAndCreateFile on a thread from the .NET thread pool:
void PauseAndCreateFile(object stateInfo) { try { string[] data = (string[])stateInfo; // wait a sec... Thread.Sleep(1000); // create a file in the temp directory string path = data[0]; string file = path + data[1]; Console.WriteLine("Creating {0} in PauseAndCreateFile...",file); FileStream fileStream = File.Create(file); fileStream.Close(); } catch(Exception e) { Console.WriteLine(e.ToString()); } }
The WaitForChanged method returns a WaitForChangedResult structure that contains the properties listed in below:
| Property | Description |
|---|---|
| ChangeType | Lists the type of change that occurred. This change is returned as a WatcherChangeTypes enumeration. The values of this enumeration can possibly be ORed together. | Name | Holds the name of the file or directory that was changed. If the file or directory was renamed, this property returns the changed name. Its value is set to null if the operation method call times out. | OldName | The original name of the modified file or directory. If this file or directory was not renamed, this property will return the same value as the Name property. Its value is set to null if the operation method call times out. | TimeOut | Holds a Boolean indicating whether the WaitForChanged method timed out (true) or not (false). |
Now, you can certainly add a timeout to the WaitForChanged call to prevent you from hanging forever on the WaitForChanged call, but that is more of a recovery option than actually performing the action you want, which is to see a file change. This mechanism could be set up in a loop to check periodically whether you should continue to monitor for this file change (user could hit “cancel” on your application in another UI thread, for example).
Popularity: 4% [?]
RSS feed for comments on this post · TrackBack URI
Leave a reply