2014-02-07 94 views
1

我希望你能幫助我一點。C#System.Timers倒計時服務器上

所以主要的問題是:我如何創建一個服務器端計時器,它有一個60秒倒計時間隔1秒,如果時間到達零,它應該做一個動作? F.E.跳過玩家的轉向。

它基於多客戶和一臺服務器的cardgame。在客戶端上,我確實有一個計時器,但我想這是沒有意義的,因爲唯一一個能夠真正看到計時器的人是他自己的玩家,所以我確實需要服務器上的邏輯來顯示時間給所有其他客戶。

這是我的代碼到目前爲止。但目前爲止沒有采取任何行動

... 
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

爲什麼不直接發送剩餘時間整數服務器,具有標誌指示它是什麼,然後讓服務器只需將其轉發給所有客戶? –

+0

我同意@StevenMills另一種選擇是,如果它是一個基於回合的遊戲,讓他們在相同的相對時間啓動計時器,然後有一個屏幕,一旦客戶端輪到它定時器觸發它的事件,告訴所有其他客戶端事件已經發生。一旦所有的客戶返回,他們收到事件就開始下一回合。 – CubanAzcuy

+0

我可以看到你的觀點,但沒有拿出那個,thx! – Linh2502

回答

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); 
     } 
    } 
} 
+0

謝謝!那幫了我很多,thx! – Linh2502