2009-07-19 51 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;

相關問題