C# 如何检测我们';你在UI线程上吗? 为了论证,考虑一个UI线程作为一个线程,它已经调用了 Apvest.Run()/或者它的一个重载调用它,并运行了一个活动的消息循环。

C# 如何检测我们';你在UI线程上吗? 为了论证,考虑一个UI线程作为一个线程,它已经调用了 Apvest.Run()/或者它的一个重载调用它,并运行了一个活动的消息循环。,c#,winforms,multithreading,ui-thread,C#,Winforms,Multithreading,Ui Thread,有没有办法检测我们当前是否在这样的线程上执行 我之所以要这样做,是因为我有一个具有长期运行的私有函数的类。该类本身已经是多线程的,并且该类的用法是可以从UI或后台线程进行处理。此功能也属于此网络。但我不希望它阻塞UI线程。因此,我想检测我是否在UI线程上运行,如果是,则将函数调用转移到后台线程中(可能是ThreadPool,但这不是本文讨论的问题)。这是完全正确的行为,但后台线程可能依赖于函数的输出,因此对它们进行阻塞更好,而UI线程则以更“设置并忘记”的方式访问它。请参见我建议这是调用者应该做

有没有办法检测我们当前是否在这样的线程上执行


我之所以要这样做,是因为我有一个具有长期运行的私有函数的类。该类本身已经是多线程的,并且该类的用法是可以从UI或后台线程进行处理。此功能也属于此网络。但我不希望它阻塞UI线程。因此,我想检测我是否在UI线程上运行,如果是,则将函数调用转移到后台线程中(可能是
ThreadPool
,但这不是本文讨论的问题)。这是完全正确的行为,但后台线程可能依赖于函数的输出,因此对它们进行阻塞更好,而UI线程则以更“设置并忘记”的方式访问它。

请参见我建议这是调用者应该做出的决定。您总是可以编写包装器方法以使其更简单,但这意味着您不会遇到调用方处于“奇怪”情况(例如,您不知道的UI框架,或其他具有事件循环的情况)而您为他们做出错误决策的问题


如果该方法需要在正确的线程中提供反馈,我会传入一个
ISynchronizeInvoke
(由
控件实现)
,以一种与用户界面无关的方式执行该操作。

如果您可以访问
表单
控件
,则可以检查属性;如果您在UI线程上,则返回
false
,如果您不在,则返回
true
。。如果它发生在无法对照
控件进行检查的上下文中,则可以轻松地在程序中设置一个可以对照检查的静态属性。在启动时存储对
Thread.CurrentThread
的引用,并在需要了解以下信息时将
Thread.CurrentThread
与该引用进行比较:

static class Program
{
    private static Thread _startupThread = null;

    [STAThread]
    static void Main()
    {
        _startupThread = Thread.CurrentThread;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public static bool IsRunningOnStartupThread()
    {
        return Thread.CurrentThread == _startupThread;
    }
}

通过调用
Program.isrunningnstartupthread
,您将得到一个
bool
,说明您是否是。

bool isMessageLoopThread=System.Windows.Forms.Application.MessageLoop

对于WPF还没有答案,因此对于记录,在WPF中,您可以使用
Application.Current.Dispatcher.CheckAccess()
的返回值来知道您是否在GUI线程上


如果当前线程是WPF中的UI线程,则返回
true

startupthread不一定是GUI线程,也不一定是唯一的GUI线程。错误:InvokeRequired在“与创建控件的线程不同的线程”上返回true@Rico:Yes,当然。我不敢相信在过去的三年里,打字错误一直存在,却没有人注意到。谢谢你抓到它,我相应地更新了答案。这是最简单的答案。