Question

Je suis en train d'utiliser le cadre réactive .NET pour simplifier certains appels asynchrones à un service WCF utilisé par une application Silverlight 3 que je vous écris.

Le problème est que je vais avoir du mal à trouver un moyen de structurer mon code d'une manière qui fonctionne. Une partie du problème, sans aucun doute, est de comprendre quels sont les mécanismes disponibles en réactifs et comment les utiliser pour résoudre mon problème.

Je suis en train d'enchaîner une série d'appels de serveur WCF - si elles étaient synchrones, ils ressemblent à ceci:

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;
}

Les appels à m_Server.XXXX() utilisés pour être directement mis en œuvre dans l'application Silveright (donc ils pourraient être synchrones) - mais maintenant sont mises en œuvre dans un service WCF. Depuis que les forces Silverlight vous d'appeler les services WCF de façon asynchrone - réécriture ce bloc de code a été difficile

.

J'espérais utiliser Observable.FromEvent<>() de souscrire aux divers événements XXXCompleted que le code proxy WCF génère, mais il est clair pour moi comment obtenir ce travail. Ma première tentative a regardé quelque chose comme:

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
Était-ce utile?

La solution

J'ai pu comprendre comment obtenir ce travail. Je signale cette réponse dans l'intérêt de partager ce que je l'ai appris.

Il se avère que décider quel thread d'exécuter un observateur souscrit sur est très important en matière de Silverlight appelle WCF. Dans mon cas, je devais veiller à ce que le code souscrit est exécuté sur le thread d'interface utilisateur - qui a été accompli par le changement suivant:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top