Обновление GUI из рабочего потока работает (WinForms), почему? - PullRequest
0 голосов
/ 11 декабря 2019

WinForms (VS2015 / .NET 4.6)

В моем фоновом потоке

 System.Threading.Tasks.Task.Run(() =>
 {
    ...
    _callback?.Progress("abcd");
    ...
 });

я вызываю GUI (_callback), который реализует интерфейс вФорма класса. Здесь я изменяю значения текстового поля, индикатора выполнения и т. Д.

void IWorkerCallback.Log(string message)
{
    _textBoxLog.AppendText($"{message}{Environment.NewLine}");
    ++_progressBar.Value;
    .... etc...
}

И все работает отлично!
Если я порваюсь с отладчиком, я вижу, что функция Form.IWorkerCallback.Log() выполняется в рабочем потокеcontext (в окне отладки Threads).

Везде сказано, что вы ДОЛЖНЫ изменять элементы GUI только в потоке GUI (там, где они созданы), в противном случае вы получите System.InvalidOperationException исключение с cross-thread operation not valid.....

Но у меня все работает нормально.

Не могли бы вы объяснить, почему?

Спасибо

1 Ответ

1 голос
/ 12 декабря 2019

Выполнение вызовов пользовательского интерфейса из другого потока - неопределенное поведение. Это может работать или нет. Чтобы получить постоянный сбой при вызовах между потоками, установите Control.CheckForIllegalCrossThreadCalls = true; в начале программы:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.checkforillegalcrossthreadcalls?view=netframework-4.8

Из документации MSDN:

КогдаПоток, отличный от потока создания элемента управления, пытается получить доступ к одному из методов или свойств этого элемента управления, что часто приводит к непредсказуемым результатам. Обычная недопустимая активность потока - это вызов неправильного потока, который обращается к свойству Handle элемента управления. Установите для CheckForIllegalCrossThreadCalls значение true, чтобы легче находить и диагностировать эту активность потока.

На низком уровне API Windows вызовы пользовательского интерфейса между потоками, которые не используют локальное хранилище потока или какие-либо другие ресурсы, специфичные для потока,может быть выполнен успешноОднако у нас все еще есть проблема синхронизации потоков, поэтому результат также не определен.

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