我希望你能帮助我一点。
所以主要的问题是:如何创建一个服务器端计时器,它具有60秒的倒计时,间隔为1秒,如果时间达到零,它应该执行一个动作? F.E.跳过一名球员。
它基于具有多客户端和一台服务器的卡片游戏。在客户端,我确实有一个计时器,但我想它没有任何意义,因为唯一可以实际看到计时器的是玩家自己,所以我确实需要服务器上的逻辑来显示时间对所有其他客户。
到目前为止,这是我的代码。但到目前为止还没有采取任何行动。
...
using System.Timers;
namespace CardGameServer{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
ConcurrencyMode = ConcurrencyMode.Reentrant)]
public sealed class Player : IPlayer
{
public Timer timer;
int remainingtime = 60;
public void timerAnzeigen()
{
timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(OnTimeEvent);
timer.AutoReset = true;
timer.Enabled = true;
timer.Start();
}
private void OnTimeEvent(object source, ElapsedEventArgs e)
{
remainingtime--;
if (remainingtime == 0)
{
drawCard();
nextPlayer();
remainingtime = 60;
}
}
答案 0 :(得分:1)
我注意到你的标签中有Visual Studio 2013,所以我假设你使用的是C#4.5。在这种情况下,我建议反对 Timer
类,而是将Task
与async/await
一起使用。
例如:
using System.Threading;
using System.Threading.Tasks;
public sealed class TaskTimer
{
Action onTick;
CancellationTokenSource cts;
public bool IsRunning { get; private set; }
public TimeSpan Interval { get; set; }
public TaskTimer(TimeSpan interval, Action onTick)
{
this.Interval = interval;
this.onTick = onTick;
}
public async void Start()
{
Stop();
cts = new CancellationTokenSource();
this.IsRunning = true;
while (this.IsRunning)
{
await Task.Delay(this.Interval, cts.Token);
if (cts.IsCancellationRequested)
{
this.IsRunning = false;
break;
}
if (onTick != null)
onTick();
}
}
public void Stop()
{
if (cts != null)
cts.Cancel();
}
}
然后在你的Player
课程中:
sealed class Player : IPlayer
{
static readonly TimeSpan OneSecondDelay = TimeSpan.FromSeconds(1);
static readonly int InitialSeconds = 60;
TaskTimer timer;
long remainingSeconds;
public int RemainingSeconds
{
get { return (int)Interlocked.Read(ref remainingSeconds); }
}
public Player()
{
ResetTimer(InitialSeconds);
timer = new TaskTimer(OneSecondDelay, TimerTick);
timer.Start();
}
void ResetTimer(int seconds)
{
Interlocked.Exchange(ref remainingSeconds, seconds);
}
void TimerTick()
{
var newValue = Interlocked.Decrement(ref remainingSeconds);
if (newValue <= 0)
{
// Timer has expired!
ResetTimer(InitialSeconds);
}
}
}