WCF和Silverlight中的Thread.Sleep

时间:2012-12-17 10:05:31

标签: wcf silverlight task-parallel-library duplex

我正在设计一个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));
        }
    }

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您可以尝试以异步方式等待。抓住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));
        }
    }

答案 2 :(得分:0)

行。由于线程或任务没有解决我的问题,我决定制作一个小技巧并使用动画占用UI线程并使用其完成的事件处理程序为我的应用程序制作延迟函数。

我先为调度员做了以下扩展,

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

我也许会向扩展程序发送一个参与动作,但目前这解决了我的问题。

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