Domanda

Sto cercando di utilizzare il Reactive Framework .NET per semplificare alcune chiamate asincrone a un servizio WCF utilizzato da un Silverlight 3 app che sto scrivendo.

Il problema è che sto avendo difficoltà a trovare un modo per strutturare il mio codice in un modo che funziona. Parte del problema, senza dubbio, è la comprensione quali meccanismi sono disponibili in reattiva e come usarli per risolvere il mio problema.

Sto cercando di stringa insieme una serie di chiamate al server WCF - se fossero sincrono, che sarebbe simile a questa:

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

Le chiamate m_Server.XXXX() usati per essere implementata direttamente all'interno dell'app Silveright (quindi potrebbero essere sincrona) - ma ora sono implementati all'interno di un servizio WCF. Dal momento che le forze di Silverlight di chiamare i servizi WCF in modo asincrono - riscrittura questo blocco di codice è stato difficile

.

speravo di utilizzare Observable.FromEvent<>() per iscriversi ai vari eventi XXXCompleted che il codice proxy WCF genera, ma non è chiaro a me come ottenere questo al lavoro. Il mio tentativo originale sembrava qualcosa di simile:

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
È stato utile?

Soluzione

Sono stato in grado di capire come ottenere questo al lavoro. Mi distacco questa risposta nell'interesse di condividere quello che ho imparato.

Risulta che decidere quale filo ad eseguire un osservatore sottoscritto il è molto importante quando si tratta di Silverlight WCF chiama. Nel mio caso, avevo bisogno di assicurarsi che il codice sottoscritto viene eseguito sul thread UI - che è stata compiuta la seguente modifica:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top