Search code examples
c#messagemessageboxbox

C# Windows Forms - Messagebox showing once more every time I run my code


I have a Windows Forms application that tests sorting algorithms.It consists of a single form.When testing completes the form displays a messagebox that says testing is done.But after the 1st test it displays once, after the 2nd it displays twice, after the 3rd three times and so on. A method that displays the MessageBox is called by a background worker from the "RunWorkerCompleted" method.

private void RunAlgorithmTests()
//this is called from an onclick method
{
    backgroundWorker.DoWork += (s, e) =>
    {
        test.RunTests();
    };

    backgroundWorker.RunWorkerCompleted += (s, e) =>
    {
        ShowCompleteMessage();
    };
    backgroundWorker.RunWorkerAsync();
}


private void ShowCompleteMessage()
//show this message on successful test complete
{
    string title = "Test završen!";
    string message = "Test završen nakon" + swatch.Elapsed.Hours.ToString() + ":" + swatch.Elapsed.Minutes.ToString() + ":" + swatch.Elapsed.Seconds.ToString();
    this.Text = "Aplikacija za testiranje algoritama sortiranja";
    if (test.complete)
    {
        MessageBox.Show(message, title);
    }
}

MessageBox should only appear once at the end of every test, but the amount of times it appears increments by every test ran.


Solution

  • The problem is that every time you run the background worker, you add additional new handlers for those two events. The first time, you've got one handler for each. Next time, you add one more, so you've got two. Both are called. Next time, you add another, and all three get called.

    What you want to do is make sure that only happens once.

    I like your idea of putting the event handler initialization in a method of its own, so we'll stick with that.

    //  Your Form class is probably called something else. 
    public Form1()
    {
        InitializeComponent();
    
        //  Since backgroundWorker was created in the form designer, it will have been 
        //  initialized in InitializeComponent(). Therefore, this has to happen after 
        //  InitializeComponent() is called. 
        InitializeBackgroundWorkerHandlers();
    }
    
    private void InitializeBackgroundWorkerHandlers()
    {
        backgroundWorker.DoWork += (s, e) =>
        {
            test.RunTests();
        };
    
        backgroundWorker.RunWorkerCompleted += (s, e) =>
        {
            ShowCompleteMessage();
        };
    }
    
    //  this is called from an onclick method
    private void RunAlgorithmTests()
    {
        backgroundWorker.RunWorkerAsync();
    }