c# - 在 Silverlight 中调用 WCF 服务时使用 Observable.FromEvent

标签 c# wcf silverlight-3.0 asynchronous system.reactive

我正在尝试使用 .NET Reactive Framework 来简化对我正在编写的 Silverlight 3 应用程序使用的 WCF 服务的一些异步调用。

问题是我很难找到一种方法来构建我的代码以一种可行的方式。毫无疑问,部分问题是了解 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

最佳答案

我能够弄清楚如何让它发挥作用。为了分享我所学到的知识,我发布了这个答案。

事实证明,在处理 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

关于c# - 在 Silverlight 中调用 WCF 服务时使用 Observable.FromEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1951823/

相关文章:

c# - 将 SqlTransaction 与 SqlDataReader 一起使用

c# - 在定义变量的类中使用 getter 和 setter?

c# - 在 wcf 服务上返回 html 格式而不是 json 或 xml

wcf - 这可能是由于服务端点绑定(bind)不使用 HTTP 协议(protocol)

silverlight - 如何将样式应用于整个 silverlight 应用程序?

c# - 了解树搜索中的 PLINQ 瓶颈

c# - 从项目内的注释或 XML 文档生成 WCF 实现/使用文档

c# - 单击控件外部时如何关闭 Silverlight 中的弹出窗口?

wpf - 如何使用双向绑定(bind)回滚 Silverlight 3 中对对象所做的更改

c# - 如何在 UML 中表示 .NET 字典类型?