Почему исключение межпотоковой операции не выдается при запуске exe в bin \ Debug - PullRequest
23 голосов
/ 20 октября 2010

Я отлаживал приложение, и где-то в коде поток пытается добраться до списка, созданного другим потоком. При попытке доступа к списку приложение выдает исключение «Межпотоковая операция недопустима: исключение: элемент управления ' listbox », доступный из потока, отличного от потока, в котором он был создан, при отладке. Однако, когда я запускаю вывод этого приложения в папке bin \ Debug, я не получаю диалоговое окно исключения и вижу, что к списку успешно обращаются из потока, не являющегося владельцем, поэтому я думаю, что здесь есть поведенческая разница , а не просто исключенное исключение. Я могу обойти это исключение при отладке со следующей строкой в ​​событии form_load

Control.CheckForIllegalCrossThreadCalls = false;

Но в чем причина такого другого поведения?

1 Ответ

40 голосов
/ 20 октября 2010

Да, это проверяется только при подключенном отладчике. Это было необходимо, потому что много кода .NET 1.x нарушало это правило. Это не очевидный.

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

Microsoft очень заботится об обратном сравнении, даже если он содержит ошибки. Исправление отлично, хотя иногда оно ошибочно (Show (owner) проверяется, когда не должно). И иногда пропускает, чтобы проверить, когда это код в рамках, который нарушает правило. Что происходит, когда зависимость потока является косвенной. Наиболее распространенные случаи этого - обновление источника данных элемента управления с привязкой к данным в рабочем потоке (сначала отмените привязку!) И использование элемента управления, который прослушивает событие SystemEvents.UserPreferenceChanged (не создавайте пользовательский интерфейс во втором потоке!) 1007 *


Для справки, соответствующий код присутствует в статическом конструкторе класса Control:

static Control()
{
    //...
    checkForIllegalCrossThreadCalls = Debugger.IsAttached;
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...