c#如何使用Web服务创建同步计时器

时间:2017-11-21 11:22:59

标签: c# winforms web-services timer thread-synchronization

我正在使用网络服务在c#windows窗体应用程序中进行多人游戏,这需要我们在游戏形式上放置一个计时器,这样当倒数计时器变为0时,它将是对手的回合。现在,这是我的计时器代码。

private void StartTimer()
{
   timeLeft = 11;
   while (TimerRunning)
   {
    if (timeLeft > 0)
     {
       if (this.InvokeRequired)
           lb_Timer.Invoke((MethodInvoker)delegate ()
           {
               timeLeft = timeLeft - 1;
               if (timeLeft < 10)
                   lb_Timer.Text = "0: 0" + timeLeft;
               else
                   lb_Timer.Text = "0: " + timeLeft;
           });
       else
       {
           timeLeft = timeLeft - 1;
           if (timeLeft < 10)
               lb_Timer.Text = "0: 0" + timeLeft;
           else
               lb_Timer.Text = "0: " + timeLeft;
       }
     }
     else
     {
       if (this.InvokeRequired)
           lb_Timer.Invoke((MethodInvoker)delegate ()
           {
               TimerRunning = false;
               lb_Timer.Text = "0:00";
           });
       else
       {
           TimerRunning = false;
           lb_Timer.Text = "0:00";

       }
       break;
    }
      Thread.Sleep(2200);
   }
}

注意:

  • 倒数计时器范围是10秒,我给出了timeleft值11,这样当计时器启动时,它将从10秒开始。
  • thread.sleep成为我的计时器的间隔,因为1000或1s太快,这就是为什么我决定把它变成2.2s。
  • 你可以给我一个关于如何在用户攻击时停止线程的建议,以便计时器重置吗?
  • 你能告诉我如何使用网络服务实现我的计时器吗?谢谢!

1 个答案:

答案 0 :(得分:0)

这是一个如何实现倒计时的简单示例。创建一个新的WinForms项目并添加两个按钮和两个标签。点击btn_Start即可开始倒计时,点击btn_Cancel即可取消。所以你可以玩一下。在您的游戏中,在倒计时任务完成布尔结果后,您可以触发事件,设置共享布尔变量,设置AutoResetEvent或...

public partial class Form1 : Form
{
  CancellationTokenSource _cancelSource = null;

  public Form1()
  {
    InitializeComponent();
  }

  private async void btn_Start_Click(object sender, EventArgs e)
  {
    btn_Start.Enabled = false;
    lb_Result.Text    = "Countdown started...";

    if(_cancelSource == null)
      _cancelSource = new CancellationTokenSource();
    else if (_cancelSource.IsCancellationRequested)
    { 
      _cancelSource.Dispose();
      _cancelSource = new CancellationTokenSource();
    }

    bool countDownCancelled = await PerformCountdown(_cancelSource.Token);

    if(countDownCancelled)
      lb_Result.Text = "Countdown cancelled";
    else
      lb_Result.Text = "Countdown finished";

    btn_Start.Enabled = true;
  }

  private void btn_Cancel_Click(object sender, EventArgs e)
  {
    if (_cancelSource != null && !_cancelSource.IsCancellationRequested)
      _cancelSource.Cancel();
  }

  private void UpdateTimeLabel(int remainingSeconds)
  {
    lb_Timer.Text = string.Format("0: {0}s", remainingSeconds);
  }

  private async Task<bool> PerformCountdown(CancellationToken cancelToken)
  {
    bool cancelled = false;

    try
    {
      int timeLeft = 3;

      Invoke((MethodInvoker)delegate() { UpdateTimeLabel(timeLeft); });
      do
      {
        await Task.Delay(1000, cancelToken);

        if (cancelToken.IsCancellationRequested)
          break;

        timeLeft--;
        Invoke((MethodInvoker)delegate() { UpdateTimeLabel(timeLeft); });
      }
      while (timeLeft > 0);
    }
    catch (OperationCanceledException)
    {
      cancelled = true;
      Debug.WriteLine("PerformCountdown cancelled");
    }
    catch (Exception ex)
    {
      Debug.WriteLine("PerformCountdown unhandled exception: " + ex);
    }

    return cancelled;
  }
}