Recipe12.24.Waiting for an Action to Occur in the Filesystem


Recipe 12.24. Waiting for an Action to Occur in the Filesystem

Problem

You need to be notified when a particular event occurs in the filesystem, such as the renaming of a 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). However, this notification must occur synchronously. In other words, the application cannot continue unless a specific action occurs to a file or directory.

Solution

The WaitForChanged method of the FileSystemWatcher class can be called to wait synchronously for an event notification. This is illustrated by the WaitForZipCreation method shown in Example 12-13, which waits for an actionmore specifically, the action of creating the Backup.zip file somewhere on the C:\ driveto be performed before proceeding on to the next line of code, which is the WriteLine statement. Finally, we spin off a thread from the ThreadPool to execute the PauseAndCreateFile method, which does the actual work of creating the file. By doing this in a background thread, we allow the FileSystemWatcher to detect the file creation.

Example 12-13. WaitForZipCreation method

 public void WaitForZipCreation(string path, string fileName) {     FileSystemWatcher fsw = null;     try     {         using (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( ));         throw;     }     // Clean it up.     File.Delete(fileName); } 

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 ThreadPool 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);         using (FileStream fileStream = File.Create(file))         {             // Use fileStream var…         }     }     catch(Exception e)     {         Console.WriteLine(e.ToString( ));         throw;     } } 

Discussion

The WaitForChanged method returns a WaitForChangedResult structure that contains the properties listed in Table 12-12.

Table 12-11. WaitForChangedResult properties

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.

TimedOut

Holds a Boolean indicating whether the WaitForChangedmethod timed out (true) or not (false).


The way we are currently making the WaitForChanged call could possibly block indefinitely. To prevent you from hanging forever on the WaitForChanged call, you can specify a timeout value of 3 seconds as follows:

 WaitForChangedResult result =          fsw.WaitForChanged(WatcherChangeTypes.Created, 3000); 

See Also

See the "FileSystemWatcher Class," "NotifyFilters Enumeration," and "Wait-ForChangedResult Structure" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net