2009-12-23 3 views
3

필자가 작성한 Silverlight 3 응용 프로그램에서 사용하는 WCF 서비스에 대한 일부 비동기 호출을 단순화하기 위해 .NET Reactive Framework를 사용하려고합니다.Silverlight에서 WCF 서비스를 호출 할 때 Observable.FromEvent 사용

문제는 제대로 작동하는 방식으로 코드를 구조화하는 데 어려움을 겪고 있다는 것입니다. 문제의 일부는 의심의 여지없이 Reactive에서 사용할 수있는 메커니즘과 내 문제를 해결하는 방법을 이해하는 것입니다.

내가 함께 문자열 WCF 서버의 일련의 호출을 시도하고있다 - 그들은 동기한다면, 그들은 같은 것을 보일 것이다 다음 Silveright 응용 프로그램 내에서 직접 구현하는 데 사용 m_Server.XXXX()

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

호출을 (따라서 이들은 동기식 일 수 있습니다) - 그러나 이제는 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 

답변

3

이 작업을 수행하는 방법을 알 수있었습니다. 나는 내가 배운 것을 나누기 위해이 대답을 게시하고있다.

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 
관련 문제