我正在设计一个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));
}
}
答案 0 :(得分:1)
我从未使用过WCF,但我相信如果您希望消息按顺序到达,则需要启用WS-ReliableMessaging。尝试阅读this。祝你好运。
TaskEx.Delay远比Thread.Sleep好,但是任何一个都非常可疑,作为(几乎)任何问题的解决方案。
答案 1 :(得分:0)
您可以尝试以异步方式等待。抓住async target pack for Silverlight with VS2012或VS2010。然后,您可以使用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 );
我也许会向扩展程序发送一个参与动作,但目前这解决了我的问题。
我希望这对其他人也有帮助。