2011-07-15 1 views
5

ディスパッチャを使用して2番目のスレッドを作成しようとしているため、(UI用の)プライマリディスパッチャに完全にストレスがなく、UIに常に応答することができます。.NET新しいディスパッチャを作成

ここでは、各サブ(またはC#ではvoid)に対して複数のスレッドを作成できましたが、新しいスレッドを1つ作成してディスパッチャを取得して呼び出すことはできません。これは私がやったことです:

Private CheckLoopThread As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf CheckLoop)) 

CheckLoopThread.Priority = System.Threading.ThreadPriority.Lowest 
CheckLoopThread.Start() 
Dim Test As Windows.Threading.Dispatcher = Windows.Threading.Dispatcher.FromThread(CheckLoopThread) 

しかし、変数 "Test"は実行 "Nothing"の後です。これはどのように可能ですか? 2番目のディスパッチャを作成する別の方法はありますか?

回答はすべての.NETフォームで評価されています。 Visual BasicまたはC#。私はVB.NET WPF .NET 4.0フレームワークで作業しています。

ありがとうございます。

+0

は、(スレッドの実行に時間はかかりませんCheckLoopの手順を実行している場合)CheckLoopThreadはそれを開始した後すぐに終了していないことを確認してください。 –

+0

チェックループにループがあり、終了しません。 –

答えて

10

Dispatcher.FromThreadはディスパッチャーを作成せず、ディスパッチャーがスレッド用にまだ作成されていない場合はnullを戻します。スレッドのディスパッチャを作成するには、CheckLoopThreadで少なくとも1回はDispatcher.CurrentDispatcherにアクセスする必要があります。それはDispatcher.CurrentDispatcherためMSDNに言うように:

ディスパッチャは、現在のスレッドに関連付けられていない場合、新しい ディスパッチャが作成されます。これは、FromThread メソッドの場合には当てはまりません。 FromThreadはnullを返します、指定されたスレッド

+0

ありがとうございました!それは確かにそれでした。 +1あなたのために。 –

5

に関連付けられているディスパッチャ がない場合、私は実際に私は適切な方法は、次の線に沿って何かだと思い、これらのディスパッチャの多くを作成しています:

object theLock = new object(); 
Dispatcher dispatcher = null; 

lock (theLock) 
{ 
    new Thread(new ThreadStart(() => 
    { 
     lock (theLock) 
     { 
      dispatcher = Dispatcher.CurrentDispatcher; 
      Monitor.Pulse(theLock); 
     } 
     Dispatcher.Run(); 
    })).Start(); 

    Monitor.Wait(theLock); 
} 

dispatcher.Invoke(...); 

すべてのロックでは複雑に見えますが、実際にはdispatcherが設定される前にStart()メソッドが返される可能性があります。そのため、呼び出すとロックなしでNullReferenceExceptionが返される可能性があります。

+0

これは私のためにやった。ありがとう! – aclave1

7

なぜロックしますか?

私が好む:

Dispatcher myDispatcher = null; 

ManualResetEvent dispatcherReadyEvent = new ManualResetEvent(false); 

new Thread(new ThreadStart(() => 
{ 
    myDispatcher = Dispatcher.CurrentDispatcher; 
    dispatcherReadyEvent.Set(); 
    Dispatcher.Run(); 
})).Start(); 

dispatcherReadyEvent.WaitOne(); 

myDispatcher.Invoke(...); 
+1

基本的な実装が同じかどうかはわかりませんが、非常に真です。 – mycroes

関連する問題