2011-07-27 26 views
2

右、私はこの時点でGUI用に何かをプログラミングしています。しかし、私は自分自身を修正するように見えない同期問題に直面しています。呼び出された(ディスパッチャを介して)呼び出し、または直接呼び出された呼び出しを同期する

UDPを使用してビデオの再生を開始/停止します。入ってくるコード/コマンドは解析され、 'Window'クラスで実行されます。

GUI要素なので、要素への呼び出しは、作成元のスレッドで実行する必要があります。しかし、私のUDPクライアントは独自のスレッドで実行されます。したがって、すべての呼び出しはDispatcher.Invokeメソッドを経由する必要があります。

しかし、うまくいきます。これには複数の問題があります。たとえば、 'load'メソッドと 'play'メソッドは、互いに直接実行できます。これは 'load'メソッドの前に 'play'メソッドを実行させる可能性があります。なぜなら、前記オブジェクトに対してアクションが呼び出されたときを制御することができないからです。

だから私は、オブジェクトにmonitor/mutex/semaphore/lock()を使用し、再び解放されるまで待つことにしました。下記のコードスニペットを参照してください。しかし、これは例外の原因となっている。

SynchronizationLockExceptionは、出口を呼び出すことにより、スローパルス、 PulseAll、およびコードの非同期の ブロックからモニタクラスのメソッドを待っています。

私は両方のスレッドを同期するためのより良い/働く方法を探しています。呼び出しがディスパッチャを通じて呼び出された場合、呼び出されたメソッドが呼び出されるまで、他のスレッドは基本的に待機します。

また、間違った用語を使用している場合は、私の言葉を言い訳にしてください。

発送方法:

#region ExecuteDispatch Members 
public void Dispatch(Callback call) 
{ 
    Dispatch(this, call); 
} 
public void Dispatch(DispatcherObject o, Callback call) 
{ 
    if (!o.Dispatcher.CheckAccess()) 
    { 
     o.Dispatcher.Invoke(
      System.Windows.Threading.DispatcherPriority.Send, 
      new Action(call) 
     ); 
    } 
    else 
    { 
     call(); 
    } 
} 
#endregion 

メソッド「同期」する必要があります。

Monitor.Enter(player); 
Dispatch(delegate() 
{ 
    player.Stop(); 
    Monitor.Exit(player); 
}); 
Monitor.Enter(player); 
Monitor.Exit(player); 

答えて

2

可能な方法の1つは、あるスレッドが、彼は彼の仕事を終えたことを他に合図することです。したがって、AutoResetEventまたはManualResetEventを使用することができます。

AutoResetEvent evt = new AutoResetEvent(false); 

Dispatch(delegate() 
{ 
    player.Stop(); 
    evt.Set(); 
}); 

evt.WaitOne(); //Here the thread waits until Set is called on evt 
+0

これは、私が必要とするように見えます。私はポップアップへの他の答えのためにちょっと待つでしょう、そうでなければこれは受け入れられます –

関連する問題