【问题标题】:Thread.Sleep in WCF and SilverlightWCF 和 Silverlight 中的 Thread.Sleep
【发布时间】:2012-12-17 10:05:30
【问题描述】:

我正在设计一款 silverlight 游戏,但我被游戏结束功能所困扰。这是一款回合制纸牌游戏,我使用的是 WCF Duplex。但是当我调用 finalize 函数时,回调在 OnFinalized 消息之前接收 OnEndGame 消息。在开始新游戏之前,我需要在客户端播放一些动画。我尝试了很多东西,包括 Thread.Sleep 和 Task.Wait 等,但我无法找出问题所在。我应该怎么做才能让 EndGame 方法返回一些时间?

    private void FinalizeGame()
    {
        this.GameState = Enums.GameState.Finalize;

        Task.Factory.StartNew(()=>{
            CalculateWinners();
            GameSubscriptionManager.Publish(SubscriptionType.GameStream, cb => cb.OnFinalize(this));
        }).ContinueWith((antecedent)=>{
            EndGame();
        });
    }

    private void EndGame()
    {
        this.GameState = Enums.GameState.None;

        Thread.Sleep(5000);

        GameSubscriptionManager.Publish(cb => cb.OnEndGame(this));
        RemovePlayersAndGetWaitingPlayers();


        if (PlayingPlayers.Count > 1)
        {
            ResetGame();
            StartGame();
        }
        else
        {
            GameState = GameState.None;
            GameSubscriptionManager.Publish(cb => cb.OnWaitingForNewPlayers(this));
        }
    }

【问题讨论】:

  • Finalize 方法在哪里调用,方法本身在哪里?
  • 这是游戏的最后阶段,计算游戏结果并开始新游戏。在服务端调用 Finalize 方法将 OnFinalize 发送到回调

标签: wcf silverlight task-parallel-library duplex


【解决方案1】:

我从未使用过 WCF,但如果您希望消息按顺序到达,我相信您需要启用 WS-ReliableMessaging。尝试阅读this。祝你好运。

TaskEx.Delay 比 Thread.Sleep 好得多,但作为解决(几乎)任何问题的解决方案,任何一个都非常可疑。

【讨论】:

  • 感谢亚历山大的帮助。当我将可靠会话放入我的服务时,我在 Fiddler 中遇到错误(此端点不支持。此端点仅处理 WS-ReliableMessaging 2005 年 2 月的消息。?????)。配置文件可能不匹配。我现在就在上面
【解决方案2】:

您可以尝试以异步方式等待。抓住async target pack for Silverlight with VS2012VS2010。然后,您可以使用 TaskEx.Delay 作为 Thread.Sleep 的替代品:

    private async Task EndGame()
    {
        this.GameState = Enums.GameState.None;

        await TaskEx.Delay(5000);

        GameSubscriptionManager.Publish(cb => cb.OnEndGame(this));
        RemovePlayersAndGetWaitingPlayers();


        if (PlayingPlayers.Count > 1)
        {
            ResetGame();
            StartGame();
        }
        else
        {
            GameState = GameState.None;
            GameSubscriptionManager.Publish(cb => cb.OnWaitingForNewPlayers(this));
        }
    }

【讨论】:

    【解决方案3】:

    好的。由于我的情况没有任何线程或任务处理,我决定做一个小技巧,使用动画来占用 UI 线程,并使用其完成的事件处理程序来为我的应用程序制作延迟功能。

    我先为dispatcher做了如下扩展,

    public static class Extensions
    {
        public static event EventHandler OnCompleted;
    
        public static void WaitForFakeAnimation(this Dispatcher dispatcher, TimeSpan timeToWait, EventHandler onCompleted)
        {
            Storyboard sb = new Storyboard();
            sb.Duration = timeToWait;
            OnCompleted += onCompleted;
            sb.Completed += (s,e) => 
            {
                OnCompleted(sb, null);
                OnCompleted -= onCompleted;
    
            };
            sb.Begin();
        }
    
    }
    

    我从我的 GameManager 类中调用它(可以被视为 ViewModel)

            EventHandler aferAnimation = (s,e) => {
                lock (syncServiceUpdate)
                {
                    AddNotification(notification);
                    // MessageBox.Show("after wait");
    
                };
            };
            this.gamePage.Dispatcher.WaitForFakeAnimation(TimeSpan.FromSeconds(15), aferAnimation );
    

    我可能也会向扩展发送一个 ref Action,但目前这解决了我的问题。

    我希望这对其他人也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多