Nano Hash - криптовалюты, майнинг, программирование

Обновление GUI из рабочего потока работает (WinForms), почему?

WinForms (VS2015/.NET 4.6)

В моей фоновой теме

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

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

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

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

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

Но он отлично работает для меня.

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

Спасибо


  • Это неопределенное поведение. Это может работать или нет. Чтобы получить постоянный сбой при вызовах между потоками, установите Control.CheckForIllegalCrossThreadCalls = true в начале программы. 11.12.2019
  • docs.microsoft. com/en-us/dotnet/api/ На более низком уровне Windows API могут успешно выполняться межпоточные вызовы пользовательского интерфейса, которые не используют локальное хранилище потока или какие-либо другие ресурсы, специфичные для потока. 11.12.2019
  • @AlexF - да, вот и все, Control.CheckForIllegalCrossThreadCalls это трюк! Если вы напишите это как ответ, я приму его. 11.12.2019
  • Вот что такое BeginInvoke() за. Его можно вызвать либо из другого потока, либо из основного потока. Вам не нужно проверять InvokeRequired. Не нужно учитывать, подключен ли у вас отладчик или нет. 11.12.2019
  • Да, я знаю это, но был удивлен, что он работает без begininvoke() 11.12.2019

Ответы:


1

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

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

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

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

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

12.12.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..