Resolution of multiple triggering of FileSystemWatcher events in C #

Source: Internet
Author: User
Tags log4net

1, problem description
The program needs to monitor file changes in a directory: Once a new file appears in the directory or the old file is overwritten, the program needs to read the file contents and process it. The following code is used:

 Public voidInitial () {System.IO.FileSystemWatcher FSW=NewSystem.IO.FileSystemWatcher (); Fsw. Filter="*.*"; Fsw. NotifyFilter= Notifyfilters.filename |Notifyfilters.lastwrite|Notifyfilters.creationtime; //ADD event handlers.Fsw. Created + =NewFileSystemEventHandler (fsw_changed); Fsw. Changed+=NewFileSystemEventHandler (fsw_changed); //Begin watching.Fsw. EnableRaisingEvents =true; } voidFsw_changed (Objectsender, FileSystemEventArgs e) {MessageBox.Show ("Changed", e.name); }

If a file changes, the change event is repeatedly triggered several times. This may result in duplicate processing of the same file.

2. Solution:
After a timer is passed in the file event processing, the timer is delayed for a period of time before the load of the new profile operation is performed. This avoids having to do a single operation on the file, triggering multiple change events, and loading the configuration file multiple times.

The Log4net code-XmlConfigurator.cs is studied, and the following changes are made to the code by reference to Log4net:
The basic idea is to use a timer, start the timer when the event is triggered, and write down the file name. When the timer comes, the file is actually processed.
(1), defining variables

Private int  - // Timer trigger Interval New  null; ListNew list<string// queue to record pending files

(2), Initialize FileSystemWatcher and timers

Fsw. Filter ="*.*"; Fsw. NotifyFilter= Notifyfilters.filename |Notifyfilters.lastwrite|Notifyfilters.creationtime; //ADD event handlers.Fsw. Created + =NewFileSystemEventHandler (fsw_changed); Fsw. Changed+=NewFileSystemEventHandler (fsw_changed); //Begin watching.Fsw. EnableRaisingEvents =true; //Create the timer that'll be used to deliver events. Set as Disabled      if(M_timer = =NULL)      {         //sets the callback function for the timer. The timer does not start at this timeM_timer =NewSystem.Threading.Timer (NewTimerCallback (onwatchedfilechange),NULL, Timeout.infinite, timeout.infinite); }

(3), file monitoring Event trigger code: Modify the timer, record the file name to be processed later

        void fsw_changed (object  sender, FileSystemEventArgs e)        {            new Mutex (  False"FSW");            Mutex. WaitOne ();             if (! files. Contains (e.name))            {                files. ADD (e.name);            }            Mutex. ReleaseMutex ();             // Reset the timer's trigger interval and only trigger once             M_timer. Change (Timeoutmillis, timeout.infinite);        }

(4), Timer Event trigger code: The actual processing of the file

        Private voidOnwatchedfilechange (ObjectState ) {List<String> backup =Newlist<string>(); Mutex Mutex=NewMutex (false,"FSW"); Mutex.            WaitOne (); Backup.            AddRange (files); Files.            Clear (); Mutex.                   ReleaseMutex (); foreach(stringFileinchbackup) {MessageBox.Show ("File Change", File +"changed"); }             }

Tidy up the above code and encapsulate it into a class that is more convenient to use:

     Public classWatchertimer {Private intTimeoutmillis = -; System.IO.FileSystemWatcher FSW=NewSystem.IO.FileSystemWatcher (); System.Threading.Timer M_timer=NULL; List<String> files =Newlist<string>(); FileSystemEventHandler Fswhandler=NULL;  PublicWatchertimer (FileSystemEventHandler watchhandler) {M_timer=NewSystem.Threading.Timer (NewTimerCallback (OnTimer),NULL, Timeout.infinite, timeout.infinite); Fswhandler=Watchhandler; }         PublicWatchertimer (FileSystemEventHandler Watchhandler,intTimerInterval) {M_timer=NewSystem.Threading.Timer (NewTimerCallback (OnTimer),NULL, Timeout.infinite, timeout.infinite); Timeoutmillis=TimerInterval; Fswhandler=Watchhandler; }         Public voidOnfilechanged (Objectsender, FileSystemEventArgs e) {Mutex Mutex=NewMutex (false,"FSW"); Mutex.            WaitOne (); if(!files. Contains (e.name)) {files.            ADD (e.name); } mutex.            ReleaseMutex (); M_timer.        Change (Timeoutmillis, timeout.infinite); }        Private voidOnTimer (ObjectState ) {List<String> backup =Newlist<string>(); Mutex Mutex=NewMutex (false,"FSW"); Mutex.            WaitOne (); Backup.            AddRange (files); Files.            Clear (); Mutex.            ReleaseMutex (); foreach(stringFileinchbackup) {Fswhandler ( This,NewFileSystemEventArgs (watcherchangetypes.changed,string.            Empty, file)); }        }}

The use of the keynote program is very simple and requires only the following 2 steps:
1. Generate timer object for file monitoring

New Watchertimer (fsw_changed, Timeoutmillis);

Where fsw_changed is your own file monitoring event code, passing it to the timer object is intended to be timed to the time when the timer object can invoke your own code that is actually used to process the file. For example:

void fsw_changed (object  sender, FileSystemEventArgs e) {   //Read file.    //Remove file from folder after reading      }

2. Correlate event handlers such as FileSystemWatcher Create/change/rename/delete to timer events

New NEW Newnew FileSystemEventHandler (watcher.  onfilechanged);

The purpose of this step is to notify the timer when any file monitoring event occurs, and the timer can be timed from the last occurrence of the event, and any event that precedes that time will only re-timer the timer without really triggering the file monitoring event.

Note that when you use the above code, the code that you really use to handle file-monitoring events is called with only E. The name is a value. Consider that the directory of files being monitored should already be known, so e. It is not unacceptable that FullPath be assigned a value of String.Empty.

Resolution of multiple triggering of FileSystemWatcher events in C #

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.