2013-03-27 3 views
2

Это мой код.C#: метод вызывается дважды подряд

BackgroundWorker exportWorker = new BackgroundWorker(); 

private void btnOK_Click(object sender, RoutedEventArgs e) 
{ 
    exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork); 
    exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted); 
    exportWorker.RunWorkerAsync(); 
} 


void ExportWorkerDoWork(object sender, DoWorkEventArgs e) 
{ 
    MethodToPerformInThisThread(); 
    **Dispatcher.Invoke(new Action(() => {MethodofAnotherThreadThatChangesUIStuff();}** 
} 

void ExportWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
} 
  • Когда я нажимаю на кнопку ОК (btnOK_Click) в первый раз, он идет вперед и работает все просто отлично.
  • Теперь, если я нажимаю на кнопки OK во второй раз после того, как код имеет окончания выполнения, код в смелых пробегов в два раза, то есть метод MethodofAnotherThreadThatChangesUIStuff(); вызывается, дважды подряд.
  • Опять же, если я нажму кнопку «ОК» в третий раз, то MethodofAnotherThreadThatChangesUIStuff(); вызывается три раза в строке.
  • и так далее.

Я хочу, чтобы MethodofAnotherThreadThatChangesUIStuff(); был вызван один раз, независимо от того, какой именно щелчок. Я имею в виду, что так все должно работать.

Что мне здесь не хватает?

Любая помощь будет действительно оценена.

+0

Возможно, отключите кнопку в методе click. – RyPope

+0

Я вижу некоторое неосторожное обращение с EventHandlers –

ответ

2

Это время вызвано тем, что эта линия:

exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork); 

выполняется внутри обработчика btnOK_Click. Если вы настраиваете события вне обработчика следующим образом:

BackgroundWorker exportWorker = new BackgroundWorker(); 
exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork); 
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted); 

private void btnOK_Click(object sender, RoutedEventArgs e) 
{ 
exportWorker.RunWorkerAsync(); 
} 

тогда все должно работать так, как вы ожидаете.

Другим вариантом было бы создать новый BackgroundWorker внутри обработчика btnOK_Click. По существу, вы бы создавали нового работника для каждого клика, настраивали его с помощью обработчиков и запускали его. Затем вы отбросите его и создайте новый для каждого клика.

9

Поскольку вы декларируете, что фон работал за пределами обработчика Click каждый раз, когда вы нажимаете кнопку, вы снова добавляете обработчики событий. Вот почему второй раз ваш метод вызывается дважды, а в третий раз он будет называться три раза ...

Чтобы решить эту проблему, добавьте обработчики событий вне метода click (например, в конструкторе) и оставьте Вызов RunAsync() в методе кликов.

+0

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

+0

Правильно ... пропустил этот маленький факт. ;) – IAbstract

3

Каждый раз, когда вы нажимаете «ОК», вы создаете новые обработчики событий, которые все вызовут ваши методы DoWork.

Поместите этот код в инициализации приложения:

exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork); 
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted); 

включает только следующий в методе btnOK_Click:

exportWorker.RunWorkerAsync(); 
Смежные вопросы