简体   繁体   中英

help. i did reuse BackgroundWorker. but the worker occured very strange behavior

help.

i did reuse BackgroundWorker. but the worker occured very strange behavior.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    //(!)note bw created at class scope, not button1_click.
    BackgroundWorker bw = new BackgroundWorker();

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        bw.DoWork+=new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.RunWorkerAsync();
        System.Console.Beep(2000, 200);
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        System.Console.Beep(1000, 200);
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        System.Console.Beep(2500, 200);
    }

}

it occured very strange behavior.

i expected beep sequence is beep(200,200)-beep(1000,200)-beep(2500,200).

yes. it did. but it's first time only.

*beep(200,200)=A
*beep(1000,200)=B
*beep(2500,200)=C

[when i click then button1 in second time]
A-B-B-C-C

[when i click then button1 in third time]
A-B-B-B-C-C-C

[when i click then button1 in fourth time]
A-B-B-B-B-C-C-C-C

???

what does this?

(*of cause, when i BackgroundWorker bw = new BackgroundWorker(); move to first line of button1_click, it works rightly)

Each time you click the button, you're adding another handler to the DoWork and RunWorkerCompleted events - so those delegates are both getting called one more time when you call RunWorkerAsync .

Personally I'd advise you to create one background worker on each click - but if you must reuse it, just attach the event handlers once (eg in the constructor).

The reason for this is that events in .NET are multicast.

Take your button click event, each time you execute this piece of code:

button1.Click += ...

you add another event handler to that click event.

Thus, the first time you execute the above code, and then click the button, your event handler will be called once.

Then, if you call the above code again , and then click the button, your event handler will be called twice. Then three times, four times, and so on.

So if you intend to reuse the BackgroundWorker object, don't execute the code that adds those two event handlers more than once either, and you should be fine.

Ideally I would attach the event handlers at the same time you construct the BackgroundWorker object, and then only call .RunWorkerAsync on your button click. However, as Jon mentions, you should think about whether you should reuse at all. If you click the button and attempt to start the worker while it is already running, you'll get exceptions.

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