简体   繁体   中英

c# Limit amount of messageboxes

Hello I've runned in to a problem again that I can't solve on my own.

I have a FileSystemWatcher named filOvervakare and uses this code to trigger a method.

filOvervakare.NotifyFilter = NotifyFilters.Size;
filOvervakare.NotifyFilter = NotifyFilters.LastWrite;

filOvervakare.Changed += new FileSystemEventHandler(filOvervakare_Changed);

This is the method:

void filOvervakare_Changed(object sender, FileSystemEventArgs e)
{
    if (MessageBox.Show("Vill du ladda upp filen " + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    {
        //code code code           
    }
}

Everytime a file is changed it is supposed to show the messagebox once. The problem is that instead of getting one messagebox it pops up like 5-6 of them and I have no idea how to fix this and I hope some of you might have a good solution. :)

Thanks!

// Morgan

This is by design, the event handler is called on a different thread for each notification. A quick fix is to set the FileSystemWatcher.SynchronizingObject property:

    public Form1() {
        InitializeComponent();
        fileSystemWatcher1.SynchronizingObject = this;
    }

But that's not a really good idea, the FSW is liable to miss notifications because it is blocked, waiting for you to click the OK button. Displaying a message box in the notification event is just not a good idea, you want to process the notifications as quickly as possible.

You could use a boolean to tell you whether you have a message box open.

private bool messageBoxIsOpen;

void filOvervakare_Changed(object sender, FileSystemEventArgs e)
{
    if (this.messageBoxIsOpen)
    {
        return;
    }

    this.messageBoxIsOpen = true;
    if (MessageBox.Show(
        "Vill du ladda upp filen " + e.Name + "?", 
        "En fil har ändrats", 
        MessageBoxButtons.YesNo, 
        MessageBoxIcon.Question) == DialogResult.Yes)
    {
       //code code code           
    }

    this.messageBoxIsOpen = false;
}

There are a few events, something like LastAccess, LastWrite etc that the file system watcher fires events on. You could check the event args for why the event was fired before displaying the message box or set the NotifyFilter property.

You can save the last changed file name in a dummy variable, and when the changed event is raised, don't show the messagebox unless the file name is different to the saved variable.

string lastChangedFileName = "";
void filOvervakare_Changed(object sender, FileSystemEventArgs e)
    {

if(lastChangedFileName != e.Name)
{
        if (MessageBox.Show("Vill du ladda upp filen " + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
        {
           //code code code           
        }
}
lastChangedFileName = e.Name;

    }

The easiest way to fix this is to declare a private bool, like so:

private bool m_IsBoxShown;

In your constructor, set the value to false. Change your code above to read like this: void filOvervakare_Changed(object sender, FileSystemEventArgs e)
{
if (m_IsBoxShown == false) { m_IsBoxShown=true; if (MessageBox.Show("Vill du ladda upp filen " + e.Name + "?", "En fil har ändrats", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
m_IsBoxShown=false; //code code code
} else { m_IsBoxShown=false; } } }

What I would recommend is having a short delay, say 10-100ms before showing the MessageBox. That way when a file changes a few times very quickly you only get one MessageBox.

In other words, when a notification comes in, start the timer. If the timer is already started, ignore the notification. When the timer triggers, stop the timer and show the MessageBox.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM