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

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

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

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

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

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

如果您有权访问FormControl ,则可以检查InvokeRequired属性; 如果您在UI线程上,则返回false如果不是,则返回false 。如果在无法检查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; } } 

通过调用Program.IsRunningOnStartupThread你会得到一个bool说你是不是。

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

请参阅在C#库中检测主线程中的运行