Winform контроль и нарезка резьбы - PullRequest
0 голосов
/ 14 ноября 2011

VB.NET threading.

Я попытался обновить текст кнопки в форме из события backgroundworker.do_work, и это не удалось, с обычным сообщением об исключении из нескольких потоков.

Однако, по чистой случайности, я также попытался обновить текст в system.windows.form.toolstripstatuslabel также из этого события backgroundworker.do_work, и он работает.

Вопрос: почему это? Возможно, потому, что существует некое неявное общее поведение с system.windows.form.toolstripstatuslabel?

спасибо всем.

Ответы [ 4 ]

1 голос
/ 14 ноября 2011

Это деталь реализации для класса ToolStripItem. Он действует как Контроль, но на самом деле не происходит от Контроля. Это элемент управления «без окон», использующий окно его владельца для рисования. Изменение свойства Text приводит к вызову метода Invalidate () владельца. В конечном итоге это вызывает метод OnPaint и вызывает рисование элемента. В пользовательском интерфейсе. Invalidate () - это потокобезопасный метод, он просто устанавливает внутренний бит состояния «это окно нуждается в событии Paint».

Хотя это позволяет избежать типичных проблем с потоками в пользовательском интерфейсе, таких как тупик или прямые сбои, на самом деле он не является полностью поточно-ориентированным. Вы можете установить свойство Text в то же время, когда работает метод рисования элемента. Заканчивается видимым текстом, который на самом деле не обновляется. Очень низкие шансы, а не ноль.

1 голос
/ 14 ноября 2011

почему это?

Это чистый шанс. Иногда это может работать на других, это может привести к сбою. Вы никогда не должны обновлять какие-либо элементы управления GUI из потоков, в которых они не были созданы (что по сути является основным потоком GUI).

0 голосов
/ 14 ноября 2011

Одна важная запутанная абстракция, о которой следует помнить о Windows Forms, - это то, что окно Handle не создается, пока оно фактически не требуется.То есть.Дескриптор не будет создан, когда вы создадите экземпляр Form.Скорее дескриптор создается lazily и имеет реальное окно hwnd только тогда, когда мы впервые получим вызов что-то вроде Show () / ShowDialog ().То есть.Если вы вызываете какой-либо из Show / ShowDilalog в завершении рабочего потока, тогда ваш дескриптор создается в рабочем потоке.Здесь никто никогда не запрашивал дескриптор формы, пока он не был получен как часть проверки InvokeRequired (асинхронизация действия публикации), которая произошла, когда рабочий поток завершил свою работу.Это может быть причиной того, что вы видите эту проблему время от времени.

0 голосов
/ 14 ноября 2011

Как вы создаете / вызываете свой фоновый рабочий поток.Вы должны делать что-то вроде ... (а это C #, а не VB)

// This would be a method in your form...
private void CallBackgroundWorker()
{
   YourBackgroundWorkerClass BGW = new YourBackgroundWorkerClass();
   BGW.WorkerReportsProgress = true;
   BGW.ProgressChanged += MyFormsBGW_ProgressChanged;
   BGW.RunWorkerAsync();
}

// this would be in your form too... to get feedback from worker to 
// let the form's interface/control update itself
protected void MyFormsBGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{ 
   this.SomeButton.Text = "whatever";
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...