2

Hi I am fairly new to C# and am testing a simple openFileDialog program. The code I currently wrote seems to be doing its job, however, the output is produced twice. Any help would be appreciated.

My code:

        watcher.Changed += new FileSystemEventHandler(OnChanged);
        watcher.Created += new FileSystemEventHandler(OnChanged);
        watcher.Deleted += new FileSystemEventHandler(OnChanged);

        watcher.EnableRaisingEvents = true;
    }

    private void OnChanged(object source, FileSystemEventArgs e)
    {

        MessageBox.Show("copying done");

        StreamReader inStream = new StreamReader(destFile);
        string line;
        string[] lineSplit;
        bool errorFound = false;

        while ((line = inStream.ReadLine()) != null)
        {   
            lineSplit = line.Split(' ');
            for (int i = 0; i < lineSplit.Length; i++)
            {
                if (lineSplit[i] == textBox2.Text)
                {
                    errorFound = true;
                    MessageBox.Show("Error found in " + e.Name);
                    MessageBox.Show("Exiting");
                    break;
                }

            }
        }
        inStream.Close();

    }

The output:

    Copying Done
    File: ..Changed
    Copying Done
    File: ..Changed

Just wondering why does it print twice?

TestNInja
  • 177
  • 2
  • 15
  • Could be related to [this question](http://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice) – stuartd Jan 13 '14 at 15:24

4 Answers4

5

Because it invokes OnChanged both on watcher.Created and watcher.Changed

Shai
  • 25,159
  • 9
  • 44
  • 67
4

You've attached to the same handler multiple times:

watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);

So if the Changed and Created events run, for example, you'll get the same output twice.

What you probably want to do is create separate methods for each event. I don't know what watcher is, but here's a general idea:

watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnCreated);
watcher.Deleted += new FileSystemEventHandler(OnDeleted);

private void OnCreated(object source, FileSystemEventArgs e)
{
    // do something when the watcher is created
}

private void OnDeleted(object source, FileSystemEventArgs e)
{
    // do something when the watcher is deleted
}
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
1

What you need to bear in mind, is that a single IO action can trigger multiple different FileSystemWatcher events.

Common file system operations might raise more than one event. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised.

MSDN

Most likely, what is happening here is that a File Creation is triggering both a Create event, and a Change event (I believe windows tends to create an initial file (triggering create) then writes to it (triggering a change)). However that depends on exactly the actions you are performing.

Obsidian Phoenix
  • 4,083
  • 1
  • 22
  • 60
0

This is how I fixed it, don't know if it was the best way, but it works!

private static void OnChanged(object source, FileSystemEventArgs e)
{
        //set EnableRaisingEvents = false at the start of the method.
        FileSystemWatcher t = source as FileSystemWatcher;
        t.EnableRaisingEvents = false;
        //do stuff that you want in the method, in my case checking for words.  
        .... 
        ....
        //Set EnableRaisintEvents true again
        t.EnableRaisingEvents = true;

}

This little fix makes sure the event only gets raised once per change, instead of twice.

TestNInja
  • 177
  • 2
  • 15