SilverlightのWCFサービスを呼び出すときにObservable.FromEventを使用して
-
21-09-2019 - |
質問
私は私が書いていることのSilverlight 3アプリケーションで使用されるWCFサービスへのいくつかの非同期呼び出しを簡素化するために、.NET Frameworkの反応を使用しようとしています。
トラブルは、私が動作するように、自分のコードを構造化する方法を見つけることに苦労してるということです。問題の一部は、疑いなく、メカニズムが反応に利用可能であり、どのように私の問題を解決するためにそれらを使用するかを理解されています。
私は一緒に文字列にWCFサーバの一連の呼び出しをしようとしている - 彼らは、同期した場合、彼らはこのようになります:
switch( CurrentVisualState )
{
case GameVisualState.Welcome:
m_gameState = m_Server.StartGame();
if( m_GameState.Bankroll < Game.MinimumBet )
NotifyPlayer( ... ); // some UI code here ...
goto case GameVisualState.HandNotStarted;
case GameVisualState.HandNotStarted:
case GameVisualState.HandCompleted:
case GameVisualState.HandSurrendered:
UpdateUIMechanics();
ChangeVisualState( GameVisualState.HandPlaceBet );
break;
case GameVisualState.HandPlaceBet:
UpdateUIMechanics();
// request updated game state from game server...
m_GameState = m_Server.NextHand( m_GameState, CurrentBetAmount );
if( CertainConditionInGameState( m_GameState ) )
m_GameState = m_Server.CompleteHand( m_GameState );
break;
}
m_Server.XXXX()
への呼び出しは(従ってそれらは同期することができる)Silverightアプリ内で直接実装する使用 - 今WCFサービス内に実装されています。 Silverlightの力以来、あなたは非同期でWCFサービスを呼び出すために - コードブロックを書き換えることはトリッキーされている。
私は、WCFプロキシコードが生成するさまざまなObservable.FromEvent<>()
イベントをサブスクライブするXXXCompleted
を使用することを期待していたが、それは仕事にこれを取得する方法を私には不明です。
var startObs = Observable.FromEvent<StartGameCompletedEventArgs>(
h => m_Server.StartGameCompleted += h,
h => m_Server.StartGameCompleted -= h );
startObs.Subscribe( e => { m_gameState = e.EventArgs.Result.StartGameResult;
if( m_GameState.Bankroll < Game.MinimumBet )
NotifyPlayer( ... ); // some UI code here ...
TransitionVisual( GameVisualState.HandNotStarted );
} ); // above code never reached...
m_Server.StartGameAsync(); // never returns, but the WCF service is called
解決
私は仕事にこれを取得する方法を見つけ出すことができました。私が学んだことを共有の利益のためにこの答えを掲示しています。
これは、SilverlightのWCF呼び出しを扱うときに加入したオブザーバを実行するためにどのスレッドを決定することは非常に重要であることが判明しました。私の場合、私は、UIスレッド上でその加入したコードの実行を保証するために必要な - 次のように変更することにより達成された。
var startObs = Observable.FromEvent<StartGameCompletedEventArgs>(
h => m_Server.StartGameCompleted += h,
h => m_Server.StartGameCompleted -= h )
.Take(1) // necessary to ensure the observable unsubscribes
.ObserveOnDispatcher(); // controls which thread the observer runs on
startObs.Subscribe( e => { m_gameState = e.EventArgs.Result.StartGameResult;
if( m_GameState.Bankroll < Game.MinimumBet )
NotifyPlayer( ... ); // some UI code here ...
TransitionVisual( GameVisualState.HandNotStarted );
} ); // this code now executes with access to the UI
m_Server.StartGameAsync(); // initiates the call to the WCF service