Pregunta

Estoy tratando de utilizar el Marco .NET reactiva para simplificar algunas llamadas asincrónicas a un servicio WCF utilizado por una aplicación de Silverlight 3 que estoy escribiendo.

El problema es que estoy teniendo dificultades para encontrar una manera de estructurar mi código de una manera que va a funcionar. Parte del problema, sin duda, es la comprensión de qué mecanismos están disponibles en reactiva y cómo usarlos para resolver mi problema.

Estoy tratando de hilvanar una serie de llamadas al servidor de WCF - si fueran sincrónica, que sería algo como esto:

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

Las llamadas a m_Server.XXXX() utilizan para implementar directamente dentro de la aplicación Silveright (por lo tanto podrían ser sincrónica) - pero ahora se apliquen en un servicio WCF. Desde que las fuerzas de Silverlight que llame a servicios WCF de forma asíncrona - reescritura de este bloque de código ha sido complicado

.

Me esperaba para usar Observable.FromEvent<>() para suscribirse a los diversos eventos XXXCompleted que genera el código proxy WCF, pero no está claro para mí cómo conseguir que esto funcione. Mi intento original, parecía algo como:

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
¿Fue útil?

Solución

yo era capaz de encontrar la manera de conseguir que esto funcione. Estoy publicar esta respuesta en el interés de compartir lo que he aprendido.

Resulta que decidir cuál de ellos para ejecutar un observador suscrito el es muy importante cuando se trata de Silverlight WCF llama. En mi caso, tenía que asegurarse de que el código se ejecuta en suscrito el hilo de interfaz de usuario - que se lleva a cabo mediante el siguiente cambio:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top