服务器上的C#System.Timers倒计时

时间:2014-02-07 15:18:05

标签: c# xaml timer visual-studio-2013

我希望你能帮助我一点。

所以主要的问题是:如何创建一个服务器端计时器,它具有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;
        }
    }

1 个答案:

答案 0 :(得分:1)

我注意到你的标签中有Visual Studio 2013,所以我假设你使用的是C#4.5。在这种情况下,我建议反对 Timer类,而是将Taskasync/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);
        }
    }
}