Как мне найти текущий исполняемый код в потоке пользовательского интерфейса? - PullRequest
1 голос
/ 13 апреля 2011

Я занимаюсь разработкой приложения silverlight, и у меня есть метод, который должен выдавать исключение, если оно запускается в потоке пользовательского интерфейса, поскольку оно использует AutoResetEvent.WaitOne () без тайм-аута, что приводит к зависанию потока пользовательского интерфейса.
Как мнеопределить, является ли текущий поток потоком пользовательского интерфейса?

РЕДАКТИРОВАТЬ:
Обратите внимание, что этот метод находится в библиотеке классов, а не в компоненте пользовательского интерфейса.

1 Ответ

1 голос
/ 13 апреля 2011

Вы можете проверить, находитесь ли вы в главном потоке пользовательского интерфейса, используя Application.Current.Dispatcher (используйте функцию CheckAccess () ).

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

Как узнать, является ли текущий исполняемый код потоком пользовательского интерфейса?

AFAIK это может быть невозможно с какой-либо определенностью, поскольку единственное реальное заметное различие (которое я видел) между фоновым потоком (пул потоков) и потоком пользовательского интерфейса - это их ApartmentState - потоки пользовательского интерфейса - STA, и доступные потоки в пуле потоков есть MTA. Это не означает, что поток STA является потоком пользовательского интерфейса. (я был бы рад, если бы кто-то сделал здесь что-то определенное) . Возможно, ваше решение состоит в том, чтобы взглянуть на это иначе - убедиться, что вызовы AutoResetEvent.WaitOne() выполняются только в потоках, которые являются MTA.

* просто попробуйте выполнить код this.Dispatcher.CheckAccess() в фоновом потоке и посмотрите, что произойдет ....

Edit:

спасибо @drow за то, что он указал, что это должен быть Silverlight ... да. Я оставлю ответ выше без изменений, так как он все еще применим для WPF. Как упомянуто @drow, нет никакого способа получить доступ к ApartmentState потока в Silverlight, и Диспетчер недоступен при использовании System.Threading.Thread.CurrentThread .

Таким образом, в качестве другой опции вы можете проверить, возвращает ли Deployment.Current.Dispatcher.CheckAccess() false , если это так, то вы находитесь в фоновом потоке (т.е. не в основном потоке пользовательского интерфейса). Я проверил это, и оно прекрасно работает.

...