使用Observable.FromEvent调用在Silverlight WCF服务时
-
21-09-2019 - |
题
我试图使用.NET框架无功,以简化由一个Silverlight 3应用程序,我正在写一个使用WCF服务的一些异步调用。
麻烦的是,我有一个很难找到一个方法来组织的方式,将工作我的代码。问题的一部分,毫无疑问,是了解什么机制在无可用以及如何使用它们来解决我的问题。
我想串起来的一系列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<>()
订阅了WCF代理代码生成各种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
不隶属于 StackOverflow