Помогите. я действительно использовал BackgroundWorker. но у рабочего произошло очень странное поведение - PullRequest
2 голосов
/ 24 июля 2011

help.

Я снова использовал BackgroundWorker.но у работника произошло очень странное поведение.

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);
    }

}

произошло очень странное поведение.

я ожидал, что последовательность звуковых сигналов - beep (200 200)-beep (1000 200) - beep (2500,200).

да.это сделал.но это только в первый раз.

*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

???

что это значит?

(* причины, когда я BackgroundWorker bw = new BackgroundWorker (); переместитьдо первой строки button1_click, она работает правильно)

Ответы [ 2 ]

4 голосов
/ 24 июля 2011

Каждый раз, когда вы нажимаете кнопку, вы добавляете другой обработчик к событиям DoWork и RunWorkerCompleted - так что эти делегаты оба вызывают еще раз, когда вы вызываете RunWorkerAsync.

Лично я бы посоветовал вам создавать одного фонового работника на каждый клик - но если вы должны использовать его повторно, просто присоедините обработчики событий один раз (например, в конструкторе).

1 голос
/ 24 июля 2011

Причина этого в том, что события в .NET являются многоадресными.

Возьмите событие нажатия кнопки, каждый раз, когда вы выполняете этот кусок кода:

button1.Click += ...

вы добавляете другой обработчик события к этому событию клика.

Таким образом, когда вы в первый раз выполните приведенный выше код, а затем нажмете кнопку, ваш обработчик событий будет вызван один раз.

Затем, если вы снова вызовете указанный выше код , а затем нажмете кнопку, ваш обработчик событий будет вызван дважды. Затем три раза, четыре раза и т. Д.

Так что, если вы намереваетесь повторно использовать объект BackgroundWorker, не выполняйте код, который добавляет эти два обработчика событий более одного раза, и у вас все будет хорошо.

В идеале я бы прикрепил обработчики событий одновременно с созданием объекта BackgroundWorker, а затем вызывал бы только .RunWorkerAsync по нажатию кнопки. Однако, как упоминает Джон, вам следует подумать о том, следует ли вам вообще использовать повторно. Если вы нажмете кнопку и попытаетесь запустить работника, когда он уже запущен, вы получите исключения.

...