2017-11-21 3 views
0

Ich mache ein Multiplayer-Spiel in C# Windows-Formular-Anwendung mit Web-Service, der uns einen Timer auf dem Spielformular setzen muss, so dass, wenn der Countdown-Timer 0 wird wäre der Gegner an der Reihe. Nun, das ist mein Timer-Code.C# Wie man einen synchronisierten Timer mit einem Web-Service macht

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

Hinweise:

  • der Countdown-Timer Spannweite 10 Sekunden ist, gab ich den Wert 11 left, so dass, wenn der Timer startet, ist es genau 10s beginnen würde.
  • Das thread.sleep wird das Intervall für meinen Timer, weil 1000 oder 1s zu schnell ist, deshalb habe ich beschlossen, es zu 2.2s zu machen.
  • können Sie mir einen Ratschlag geben, wie man den Thread stoppt, wenn der Benutzer angreift, damit der Timer zurückgesetzt wird?
  • können Sie mir eine Idee oder Tipps geben, wie ich meinen Timer über den Webservice implementieren soll? Danke!
+0

Ich denke, der gegeben ‚Starttimer()‘ Methode ist eine Worker-Thread-Callback-Methode, habe ich recht? Aber wenn Sie den Thread für 2200ms mit 10 multiplizieren, ist dies 22s, nicht 10s. Sie sollten Ihren kopierten Code (für den Aufruf) auch in Methoden einfügen, die aufgerufen werden können und die nicht so fehleranfällig sind. Sehen Sie sich die Klasse 'Task' und die Struktur 'CancellationToken' im Namensraum 'System.Threading.Tasks' an. – KBO

+0

Danke für den Vorschlag KBO! schau dir das später an, und was meinst du mit dem kopierten Code? Der, den ich nannte, um den Start-Timer zu starten? –

Antwort

0

Hier ist ein einfaches Beispiel, wie ein Countdown implementiert werden kann. Erstellen Sie ein neues WinForms-Projekt und fügen Sie zwei Schaltflächen und zwei Beschriftungen hinzu. Ein Klick auf btn_Start startet den Countdown, ein Klick auf btn_Cancel bricht ab. Du kannst also ein bisschen herumspielen. In Ihrem Spiel, nachdem der Countdown Aufgabe mit dem Booleschen Ergebnis beendet hat, können Sie ein Ereignis auslösen, stellen eine gemeinsame boolean Variable, stellen eine AutoResetEvent oder ...

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; 
    } 
} 
Verwandte Themen