Найти владельца потока управления графическим интерфейсом - PullRequest
2 голосов
/ 26 февраля 2010

Работая с приложением .NET, я запустил исключение «операция с несколькими потоками недопустима», только, похоже, это происходит в правильном потоке. Есть ли способ узнать, в каком потоке был создан определенный элемент управления?

Что я нашел до сих пор:

Операция «InvokeRequired» сообщает только ЕСЛИ текущий поток является «потоком владельца» ... Немного забавного времяпровождения с Reflector в методе Control.Invoke(...) привело меня к методу P / Invoke в user32.dll, который получает идентификатор потока из дескриптора окна:

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern int GetWindowThreadProcessId(HandleRef hWnd, out int lpdwProcessId);

Ответы [ 4 ]

3 голосов
/ 26 апреля 2010

Я столкнулся с той же проблемой. Я получаю это исключение даже при использовании элемента управления из потока пользовательского интерфейса. В моем случае я использовал InvokeRequired (или Invoke) в фоновом потоке до создания Handle элемента управления. Это было контекстное меню иконки в трее, и какой-то фоновый поток должен был изменить значение пункта меню. Если пользователь никогда не открывал контекстное меню, дескриптор никогда не создавался, элемент управления никогда не был привязан к потоку пользовательского интерфейса, и происходил хаос. Когда это происходило, InvokeRequired всегда возвращал false, а Invoke просто запускал метод в текущем потоке (который не был потоком пользовательского интерфейса), и поэтому Handle был создан в фоновом потоке, и элемент управления был навсегда привязан в этот поток, как если бы фоновый поток был его потоком пользовательского интерфейса. И при попытке использовать элемент управления потоком пользовательского интерфейса возникло исключение между потоками. С другой стороны, если пользователь откроет контекстное меню до запуска каких-либо фоновых потоков, все будет работать нормально.

Решением было вызвать метод CreateControl() из потока пользовательского интерфейса при запуске, прежде чем какой-либо фоновый поток сможет "украсть" элемент управления и повредить владение потоком.

0 голосов
/ 26 февраля 2010

Control.BeginInvoke () всегда работал нормально для меня. Попробуй.

0 голосов
/ 01 апреля 2010

Попробуйте использовать приложение Spy ++, оно поставляется с VS и показывает список окон (большинство элементов управления - это отдельные подокна) и некоторую информацию о них.

0 голосов
/ 26 февраля 2010

Можете ли вы захватить идентификатор потока при создании события в обработчике и сравнить его с тем, когда вы получаете исключение. Это по крайней мере скажет вам, если вы находитесь в той же теме.

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