Небольшое уточнение, хотя обычно есть только 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;
}