Как я могу узнать, выполняется ли метод в потоке пользовательского интерфейса или нет в отрыве? - PullRequest
6 голосов
/ 25 мая 2009

Вот проблема, с которой я столкнулся: мне нужно убедиться, что объект создан в потоке пользовательского интерфейса. Если это не так, он должен выбросить исключение. Но как проверить внутри метода, работает ли он в потоке пользовательского интерфейса? Примечание: я не хочу передавать какую-либо информацию в конструктор объекта.

Идеальным кандидатом был бы DispatcherSynchronizationContext (реализация SynchronizationContext в WPF), который внутренне содержит ссылку на Dispatcher, которая ссылается на поток, с которым он связан, но, к сожалению, это поле является закрытым, поэтому у меня нет возможности получить к нему доступ. *

Ответы [ 2 ]

9 голосов
/ 25 мая 2009

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

Лучший способ, который я нашел для достижения этой цели, - это использование SynchronizationContext. И WPF, и WinForms установят SynchronizationContext в любом потоке, в котором они работают. Это функция, которую я использую, если я не привязан к какой-либо конкретной модели пользовательского интерфейса.

public bool IsPossiblyUIThread() {
  return SynchronizationContext.Current != null;
}

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

A немного Более надежный способ сделать это заключается в следующем. Но для этого необходимо указать хотя бы часть WPF.

public bool IsLikelyWpfUIThread() {
  var context = SynchronizationContext.Current;
  return context != null && context is DispatcherSynchronizationContext;
}
2 голосов
/ 25 мая 2009

Dispatcher.CheckAccess () возвращает значение true, если ваш код работает в том же потоке, что и диспетчер. Должно работать, если есть только один Dispatcher / UIThread.

...