2009-07-19 52 views
13

为了论证的缘故,可以将UI线程视为一个已调用Application.Run()或调用它的重载之一的线程,并且具有正在运行的活动消息循环。如何检测我们是否在UI线程上?

有没有一种方法来检测我们目前是否正在执行这样的线程?

我想要这个的原因是因为我有一个具有长时间运行的私有函数的类。这个类本身已经是多线程的,并且这个类的用法是这样的,它可以从UI或后台线程进行处理。这个功能也落入这个网络。但我不希望它阻塞UI线程。所以我想检测一下是否在UI线程上运行,如果是这样,请将函数调用分支到后台线程(可能ThreadPool,但这对本次讨论来说不是问题)。这是完全良好的行为,但后台线程可能依赖于函数的输出,所以阻塞它们会更好,而UI线程以更“一劳永逸”的方式访问它。

回答

7

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

如果该方法可能需要以提供正确的线程反馈,我想传递一个ISynchronizeInvoke(由Control实现)做的UI不可知的方式。

12

如果你有机会到FormControl,你可以检查InvokeRequired财产;如果你在UI线程上,这将返回false,如果你不在,则返回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; 
    } 
} 

通过调用Program.IsRunningOnStartupThread你会得到一个bool说,如果你是与否。

+0

startupthread不一定是GUI线程或唯一的GUI线程。 – 2009-07-19 08:04:00

+1

错误:InvokeRequired返回true,如果在“与创建控件的线程不同的线程上” – 2012-11-01 11:38:38

8

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

相关问题