2016-06-16 21 views
3

私はthis person hadと同じ問題があります。しかし、質問は.Net 4.5を使って答えられましたが、私は.Net 4.0しか持っていません。.Net 4.0でLock()内からUIスレッドを呼び出すメソッド

private void Foo() 
{ 
    try 
    { 
     Semaphore.WaitAsync().ContinueWith(previousTask => 
     { 
      if (Dispatcher.FromThread(Thread.CurrentThread) != null) 
      { 
       Bar(); 
      } 
      else 
      { 
       Application.Current.Dispatcher.Invoke(new Action(() => Bar())); 
      } 
     }); 
    } 
    finally 
    { 
     Semaphore.Release(); 
    } 
} 

これはしかし私のために動作しません、バーを並列に呼び出されます。だから私はthis tutorialに基づいて自分の非同期セマフォを作成し、anwerを掲載男の追加のコメントに基づいて私のコードを実装し

+0

非同期が発生する前にセマフォを解放しています。あなたはすべてのものの代わりに 'await'を使うべきです。 – SLaks

+0

@SLaks:私は.Net 4.5を持っていません。 – gartenriese

+1

次に、Microsoft.Bcl.Asyncを使用します。 – SLaks

答えて

4

セマフォをリリースするのが早すぎます。終了時にContinueWithハンドラで解放してください。

Foo()は、同期されたコードが実際に実行されているかどうかに関係なく、すぐに復帰することをご存知ですか?

if (Dispatcher.FromThread(Thread.CurrentThread) != null)も非常に疑わしいです。あなたがマーシャリングする必要があるかどうかを知っている必要があります。

継続がインライン化できるため、実際に実行されるスレッドを予測することは困難です。これは、TPLでは非常に厄介な非決定論です。おそらく、その継続のUIタスクスケジューラを指定するべきです。そうすれば、マーシャリングする必要はありません。

また、.NET 4.0でawaitを使用できることに注意してください。おそらく、この質問は疑問です。

関連する問題