Я запускаю BackgroundWorker
, которые предположительно обновят мой UserControl
. Я попытался Призывая после проверки InvokeRequired
свойства:Вызов элемента управления из фонового рабочего стола без ошибок
private void bgwHighlightText_DoWork(object sender, DoWorkEventArgs e)
{
tmpRich.SelectedRtf = myRtf;
if (_ucResultRich.InvokeRequired && _ucResultRich.rchResult.InvokeRequired)
_ucResultRich.Invoke(new Action(() => _ucResultRich.rchResult.Rtf = tmpRich.Rtf)); // Debug pointer stops here
//Rest of the code
}
Я также попытался вызвать RichTextBox
внутри моего UserControl
непосредственно:
_ucResultRich.rchResult.Invoke(new Action(() => _ucResultRich.rchResult.Rtf = tmpRich.Rtf));
Но когда я отладки кода, он просто прекращает работу остальной части кода без ошибок.
Оба _ucResultRich.InvokeRequired
и _ucResultRich.rchResult.InvokeRequired
возвращение true
.
Я делаю что-то неправильно здесь?
Update
Я поставил Invoke
участие в try catch
, и теперь я могу получить следующее сообщение об ошибке с сообщением исключения:
Cross-thread operation not valid: Control '' accessed from a thread
other than the thread it was created on.
Это потому, что не могу определить контроль? Потому что он показывает это как Control ''
.
Весь смысл BackgroundWorker легко создать 2 потоки: один для графического интерфейса и еще один для чего-то другого. Он включает в себя все, что требуется для идеальной связи между обоими потоками, но вы должны использовать его правильно. Событие 'DoWork' запускает поток backgroundworker и, следовательно, вы не можете изменить то, что принадлежит нишу GUI (например, любого элемента управления).Чтобы выполнить какие-либо изменения в элементах управления, вам нужно либо дождаться завершения потока backgroundworker (через событие «RunWorkerCompleted»), либо вызвать «WorkerReportsProgress» (+ знать, как его использовать) ... – varocarbas
... Вкратце: вы должны либо научитесь правильно использовать фонового рабочего или вообще не использовать его (существуют другие подходы многопоточности). То, что вы пытаетесь ('Invoke'), не имеет никакого смысла: вы смешиваете разные подходы (а не максимизируете основную причину использования фонового рабочего, простоту встроенных функций), что обычно приводит к ошибкам, которые должны никогда не бывает (= те, которые получены из-за неправильного использования данной переменной). – varocarbas
Вы получаете хорошую диагностику, контроль с проблемой на самом деле не имеет имени. Это 'tmpRich'. Независимо от того, что вы делаете, вы получите это исключение, _ucResultRich принадлежит вашему потоку пользовательского интерфейса, а tmpRich принадлежит вашему рабочему потоку. Это произошло, когда вы назначили его свойство Rtf. Вам придется переосмыслить это, очень высокие шансы, конечно, что вы обнаружите, что больше нет смысла использовать рабочий поток, потому что вся реальная работа * должна быть выполнена потоком пользовательского интерфейса. Вы можете переделать и присвоить _ucResultRich.Rtf в обработчике событий RunWorkerCompleted с помощью e.Result. –