2009-07-19 5 views
13

引数のために、Application.Run()への呼び出しを持っていたスレッド、またはそのオーバーロードの1つが呼び出され、アクティブなメッセージループが実行されているスレッドとして考えます。UIスレッドであるかどうかを検出する方法は?

私たちがこのようなスレッドで現在実行しているかどうかを検出する方法はありますか?

長時間実行しているプラ​​イベート関数を持つクラスがあるためです。クラス自体はすでにマルチスレッド化されており、このクラスの使用法は、UIまたは処理を行っているバックグラウンドスレッドから使​​用できるようになっています。この関数もこのネットに入ります。しかし、私はUIスレッドをブロックしたくありません。だから、私はUIスレッドで実行されているかどうかを検出したい場合は、バックグラウンドスレッドに関数呼び出しをフォークします(おそらくThreadPoolですが、このディスカッションでは問題ありません)。これは完全に正常に動作しますが、バックグラウンドスレッドは関数の出力に依存している可能性が高いため、UIスレッドがより「設定と忘却」の方法でアクセスしているのに対して、それらのブロッキングはより優れています。

答えて

7

を参照してください。あなたはいつでも簡単にラッパーメソッドを書くことができますが、それは呼び出し元が「奇妙な」状況にあることに問題がないことを意味します(例えば、あなたが知らないUIフレームワーク、またはイベントループを持つ何か他のもの)あなたはそれらのために間違った決定をしています。

この方法でも正しいスレッドでフィードバックを提供する必要がある場合は、ISynchronizeInvokeControlで実装)を渡して、UIにとらわれない方法で対応します。

12

FormまたはControlにアクセスできる場合は、InvokeRequiredプロパティを確認できます。これはUIスレッドの場合はfalse、そうでない場合はtrueを返します。Controlと照合できないコンテキストで発生した場合は、チェックできる静的プロパティを簡単に設定できます。起動時にThread.CurrentThreadへの参照を格納し、あなたが知っておく必要がある場合、その参照にThread.CurrentThreadを比較:あなたがあるかどうProgram.IsRunningOnStartupThreadを呼び出すことによって

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; 
    } 
} 

あなたはbool言ってを取得します。

+0

startupthreadは必ずしもGUIスレッドまたは唯一のGUIスレッドである必要はありません。 –

+1

WRONG:InvokeRequiredは、「コントロールが作成されたスレッドとは異なるスレッド」の場合にtrueを返します。 –

+1

@Rico:もちろん、そうです。私はタイプミスがここ3年間何も気付いていないと信じられません。それをキャッチしてくれてありがとう、私はそれに応じて答えを更新しました。 –

8

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

+0

これは私の目的のための最も単純な答えです。 – ToolmakerSteve

関連する問題