Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# FileSystemWatcher triggers twice when listening to OnChanged

Trying to implement FileSystemWatcher but the OnChanged function is called twice when the file is saved. based on some other posts, I suspect the LastWrite filter has multiple events? I thought the NotifyFilters would limit it to only firing when the file is written to, but something else is causing the function to run twice. e.ChangeType only tells me the file changed, but not exactly how. Is there a way to limit this to running only once?

    public MainWindow()
    {
        InitializeComponent();

        FileSystemWatcher fsw = new FileSystemWatcher(path);
        fsw.NotifyFilter = NotifyFilters.LastWrite;
        fsw.EnableRaisingEvents = true;
        fsw.Changed += new FileSystemEventHandler(OnChanged);
    }

    private void OnChanged(object sender, FileSystemEventArgs e)
    {
        if (newString == null)
        {
            using (StreamReader sr = new StreamReader(new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                lastString = sr.ReadToEnd();
            }
            difference = lastString;
        } else {
            using (StreamReader sr = new StreamReader(new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                newString = sr.ReadToEnd();
            }
            int newCount = newString.Count();
            int count = lastString.Count();
            // MessageBox.Show("last:" + lastString.Count().ToString(), "next: " + newString.Count());
            difference = newString.Remove(0,5);
            lastString = newString;
        }
        Application.Current.Dispatcher.Invoke(new Action(() => { tb_content.Text = difference; }));
        MessageBox.Show(e.ChangeType.ToString(), "");
    }
}
like image 889
Skinner Avatar asked Oct 24 '25 14:10

Skinner


2 Answers

You can filter it out yourself, as I've posted here.

like image 151
Frederik Gheysels Avatar answered Oct 26 '25 04:10

Frederik Gheysels


An alternative to Frederik's answer:

A small workaround that comes to mind would be to prevent the OnChanged method from executing if it is already executing.

For example:

private bool IsExecuting { get; set; }

private void OnChanged(object sender, FileSystemEventArgs e)
{
    if (!IsExecuting) 
    {
        IsExecuting = true;

        // rest of your code

        IsExecuting = false;
    }
}
like image 21
Omar Himada Avatar answered Oct 26 '25 04:10

Omar Himada



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!