如何检测我们是否在UI线程上?

Mat*_*ley 13 c# multithreading ui-thread winforms

为了参数起见,将UI线程视为一个线程,该线程已调用Application.Run()或调用其中一个重载,并且有一个活动的消息循环正在运行.

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

我想要这个的原因是因为我有一个具有长期运行的私有函数的类.该类本身已经是多线程的,并且该类的使用使得它可以从UI或后台线程进行处理.这个功能也属于这个网络.但我不希望它阻止UI线程.所以我想检测我是否在UI线程上运行,如果是这样,将函数调用转换为后台线程(可能ThreadPool,但这对于此讨论来说不是问题).这完全表现良好,但后台线程可能依赖于函数的输出,因此阻塞它们更好,而UI线程以更"一劳永逸"的方式访问它.

Fre*_*örk 12

如果您有权使用a Form或a Control,则可以查看InvokeRequired酒店; false如果你在UI线程上,true如果你不在,那么它将返回..如果它发生在你无法检查的上下文中,你可以Control在程序中轻松设置一个你可以检查的静态属性.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过电话Program.IsRunningOnStartupThread,bool如果你是否,你会得到一个说法.


小智 9

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


Jon*_*eet 7

我建议这是调用者应该做出的那种决定.您总是可以编写包装器方法以使其更容易 - 但这意味着您不会遇到调用者处于"奇怪"情况的问题(例如,您不了解的UI框架,或其他具有事件循环的东西)并且你为他们做出了错误的决定.

如果该方法需要在正确的线程中提供反馈,我将传入ISynchronizeInvoke(通过实现Control)以与UI无关的方式执行此操作.


hen*_*non 7

WPF 还没有答案,因此郑重声明,在 WPF 中,您可以使用 返回值 来Application.Current.Dispatcher.CheckAccess()了解您是否位于 GUI 线程上。

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