سؤال

أحاول استخدام .NET Reactive Framework لتبسيط بعض المكالمات غير المتزامنة لخدمة WCF المستخدمة من قبل تطبيق Silverlight 3 الذي أكتبه.

المشكلة هي أنني أواجه صعوبة في إيجاد طريقة لتنظيم الكود الخاص بي بطريقة تعمل. جزء من المشكلة ، بلا شك ، هو فهم الآليات المتوفرة في التفاعل وكيفية استخدامها لحل مشكلتي.

أحاول تجميع سلسلة من مكالمات خادم 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 Services بشكل غير متزامن - فقد كانت إعادة كتابة كتلة الكود هذه صعبة.

كنت آمل في الاستخدام 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. في حالتي ، كنت بحاجة إلى التأكد من أن التعليمات البرمجية المشتركة تعمل على مؤشر ترابط واجهة المستخدم - والتي تم إنجازها من خلال التغيير التالي:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top