Я пытаюсь использовать .NET Reactive Framework, чтобы упростить некоторые асинхронные вызовы службы WCF, используемой приложением Silverlight 3, которое я пишу.
Беда в том, что мне трудно найти способ структурировать мой код так, чтобы он работал. Несомненно, частью проблемы является понимание того, какие механизмы доступны в Reactive и как их использовать для решения моей проблемы.
Я пытаюсь связать воедино серию вызовов сервера 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 асинхронно - переписать этот блок кода было сложно.
Я надеялся использовать Observable.FromEvent<>()
для подписки на различные XXXCompleted
события, которые генерирует прокси-код WCF, но мне неясно, как заставить это работать. Моя первоначальная попытка выглядела примерно так:
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