TestNInja
TestNInja

Reputation: 187

why is this C# code producing output twice

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?

Upvotes: 2

Views: 619

Answers (4)

TestNInja
TestNInja

Reputation: 187

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.

Upvotes: 0

Obsidian Phoenix
Obsidian Phoenix

Reputation: 4155

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.

Upvotes: 1

Grant Winney
Grant Winney

Reputation: 66449

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
}

Upvotes: 4

Shai
Shai

Reputation: 25619

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

Upvotes: 5

Related Questions