Как мне узнать, находится ли текущий исполняемый код в потоке пользовательского интерфейса?
Я занимаюсь разработкой приложения silverlight, и у меня есть метод, который должен генерировать исключение, если оно выполняется в потоке пользовательского интерфейса, поскольку оно использует AutoResetEvent.WaitOne() без тайм-аута, что приводит к зависанию потока пользовательского интерфейса.
Как определить, является ли текущий поток потоком пользовательского интерфейса?
РЕДАКТИРОВАТЬ:
Обратите внимание, что этот метод находится в библиотеке классов, а не в компоненте пользовательского интерфейса.
1 ответ
Вы можете проверить, находитесь ли вы в главном потоке пользовательского интерфейса, используя Application.Current.Dispatcher
(используйте функцию CheckAccess()).
Заметьте, я сказал, что основной поток пользовательского интерфейса - это важно, поскольку с любым потоком может быть связан диспетчер *, и вы можете иметь более одного потока пользовательского интерфейса. Чтобы быть более точным, ваш вопрос должен быть
Как мне узнать, является ли текущий исполняемый код потоком пользовательского интерфейса?
AFAIK это может быть невозможно с какой-либо определенностью, поскольку единственное реальное заметное различие (которое я видел) между фоновым потоком (пул потоков) и потоком пользовательского интерфейса - это их ApartmentState - потоки пользовательского интерфейса являются STA, а потоки доступны в потоке Бассейн МТА. Это не означает, что поток STA является потоком пользовательского интерфейса.(Я был бы рад, если бы кто-то сделал что-то определенное здесь). Возможно, ваше решение состоит в том, чтобы взглянуть на это иначе - убедиться, что AutoResetEvent.WaitOne()
вызовы выполняются только на потоках, которые являются MTA.
* просто попробуйте выполнить кодthis.Dispatcher.CheckAccess()
на фоне темы и посмотрим что получится....
Редактировать:
спасибо @drow за указание, что это должен быть Silverlight... да. Я оставлю вышеупомянутый ответ без изменений, так как он все еще применим для WPF. Как упомянуто @drow, нет способа получить доступ к ApartmentState потока в Silverlight, и диспетчер недоступен при использовании System.Threading.Thread.CurrentThread.
Так что в качестве другого варианта вы можете проверить, Deployment.Current.Dispatcher.CheckAccess()
возвращает false, если это так, то вы находитесь в фоновом потоке (т.е. не в основном потоке пользовательского интерфейса). Я проверил это, и это прекрасно работает.