0

私はSilverlightゲームを設計していますが、ゲームの終了機能にこだわっています。ターン制のカードゲームで、WCFデュプレックスを使用しています。しかし、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));
        }
    }
4

3 に答える 3

1

私はWCFを使用したことがありませんが、メッセージを順番に受信する場合は、WS-ReliableMessagingを有効にする必要があると思います。これを読んでみてください。幸運を。

TaskEx.DelayはThread.Sleepよりもはるかに優れていますが、どちらも(ほとんど)問題の解決策として非常に厄介です。

于 2012-12-17T21:40:06.333 に答える
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 );

拡張機能にもrefアクションを送信する可能性がありますが、現在これで問題は解決しました。

これが他の人にも役立つことを願っています。

于 2012-12-20T14:47:28.270 に答える
0

非同期の方法で待機を試みることができます。VS2012またはVS2010で Silverlight 用の非同期ターゲット パックを取得します。その後、Thread.Sleep の代わりに TaskEx.Delay を使用できます。

    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));
        }
    }
于 2012-12-17T16:10:19.010 に答える