2010-06-28 2 views
1

Я использую BackgroundWorker, чтобы избежать замораживания пользовательского интерфейса при работе с методом, который использует ожидания обрабатывает, и этот метод используется для рисования на панели в интерфейсе и имеет панель недействительности внутри ,Проблема с BackgroundWorker

something() 
{ 
    draw() 
    panel.invalidate() 
    A.waitone(500) 

} 

Проблема заключается в том, иногда работник застревает в середине рисунка, и когда я снова нажмите на кнопку пуска работник он снова работает и не застревают, это означает, что он не застрял из-за будучи занятым, так что рисунок, который застрял не Рабочий, но у меня есть аннулирование после каждой ничьей, так что любые идеи?

+0

Невозможно сказать, что не так с кодом вашего сообщения ... пожалуйста, напишите больше кода. Где установлен набор WaitHandle? –

ответ

1

Если вы хотите, чтобы фоновый процесс для обновления пользовательского интерфейса, вам нужно использовать метод элемента управления «Вызов» (это будет гарантировать, что код выполняется в потоке пользовательского интерфейса, а не в фоновом потоке):

something() 
{ 
    panel.Invoke(new Action(() => {this.draw(); panel.Invalidate();}); 
    A.waitone(500) 
} 

Или без лямбда

something() 
{ 
    panel.Invoke((MethodInvoker)delegate{ this.draw(); panel.Invalidate();}); 
    A.waitone(500) 
} 

EDIT: после просмотра нового комментария на другой ответ - вы можете обернуть каждый в каждый элемент управления вызова в вызове «Invoke» во время многопоточного обработки, поэтому вместо вызова сам метод draw() в вызове использует метод draw() Invoke, когда это необходимо для обновления пользовательского интерфейса.

+0

Спасибо, я попробовал второй, и это сработало отлично, но я все еще беспокоюсь о том, чтобы снова застрять, это кажется сумасшествием, но нужно ли мне доверять? – Lisa

+0

Я использую много вызовов для длительных задач, чтобы показать диалог прогресса/отмена пользователю - еще не подвел меня :) –

1

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

(Из комментариев)

Я пытаюсь сделать что-то шаг за шагом, поэтому мне нужно waithandles

Если вы хотите, чтобы сделать шаг за шагом, задерживая между каждым шагом, то я был бы склонен использовать System.Windows.Forms.Timer, а не ждать на waithandle. Установите таймер на нужную вам частоту, и когда он стреляет, нарисуйте немного больше того, что вы рисуете.

+0

Зачем?!?! Я не могу выполнить то, что хочу, не обращаясь к элементам пользовательского интерфейса из BackGroundWorker. – Lisa

+1

Почему? Поскольку фоновый рабочий работает в своем потоке, и вы не можете обращаться к элементам GUI из других потоков, кроме потока графического интерфейса. Возможно, вам удастся пропустить материал, который вам нужен второму работнику, но вы должны сказать нам конкретно, что вы пытаетесь сделать. – nos

+0

Я пытаюсь сделать что-то шаг за шагом, поэтому мне нужны waithandles, и поэтому мне нужно аннулировать панель, и я не хочу, чтобы пользовательский интерфейс зависал при рисовании, поэтому мне нужно использовать BackGroundWorker. – Lisa

Смежные вопросы