首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >倒计时服务器上的C# System.Timers

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

Stack Overflow用户
提问于 2014-02-07 15:18:04
回答 1查看 836关注 0票数 1

我希望你能帮我一把。

因此,主要的问题是:我如何创建一个服务器端计时器,它有一个60秒的倒计时间隔1秒,如果时间达到零,它应该做一个动作?f.e.跳过一名球员的回合。

它基于一个多功能和一个服务器的纸牌游戏。在客户端上,我确实有一个计时器,但我想这没有任何意义,因为唯一真正能看到定时器的人就是播放器自己,所以我确实需要服务器上的逻辑来向所有其他客户端显示时间。

到目前为止这是我的密码。但到目前为止还没有行动。

代码语言:javascript
运行
复制
...
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;
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-07 15:44:34

我在标签中注意到Visual 2013,所以我假设您使用的是C# 4.5。在这种情况下,我建议不要使用Timer类,而是在async/await中使用Task

例如:

代码语言:javascript
运行
复制
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类中:

代码语言:javascript
运行
复制
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);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21631347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档