it-swarm.com.de

Wie kann ich eine kurze Verzögerung in C # ausführen, ohne den Schlaf zu verwenden?

Ich bin unglaublich neu im Programmieren, und ich habe bis jetzt gut genug gelernt, denke ich, aber ich kann mich immer noch nicht mit der Idee auseinandersetzen, eine Verzögerung so zu gestalten, wie ich es will. Woran ich gerade arbeite, ist eine Art Testspiel mit einer Windows Forms-Anwendung, die ein Kampfsystem beinhaltet. Darin möchte ich einen NPC erstellen, der alle paar Sekunden eine Aktion ausführt. Das Problem ist, ich möchte dem Spieler auch erlauben, zwischen Angriffen zu interagieren. Thread.sleep scheint wirklich nicht für mich zu funktionieren, nicht nur, weil ich nicht weiß, wie man Multithread verwendet, sondern wann immer ich versuche, es auszuführen, sagen Sie Folgendes: 

 textBox1.Text += "\r\nThread Sleeps!";
 System.Threading.Thread.Sleep(4000);
 textBox1.Text += "\r\nThread awakens!";

Es scheint darauf zu bestehen, zuerst zu schlafen und dann beide Zeilen zu drucken. 

Ich denke, das ist alles, was ich im Moment sagen kann, aber wenn das immer noch zu vage oder zu wortreich ist, können Sie es mir gerne sagen. 

Kurz gesagt: In C # möchte ich etwas vor dem Start verzögern, gleichzeitig aber noch Benutzerinteraktion zulassen.

21
user2706003

Wenn Sie .NET 4.5 verwenden, können Sie mit dem neuen async/await-Framework schlafen, ohne den Thread zu sperren. 

Es funktioniert so, dass Sie die Funktion, die asynchrone Operationen benötigt, mit dem Schlüsselwort async markieren. Dies ist nur ein Hinweis an den Compiler. Dann verwenden Sie das Schlüsselwort await in der Zeile, in der der Code asynchron ausgeführt werden soll. Das Programm wartet, ohne den Thread oder die Benutzeroberfläche zu sperren. Die von Ihnen aufgerufene Methode (in der Warteschlangenzeile) muss ebenfalls mit einem async-Schlüsselwort markiert werden. Sie wird normalerweise als Async bezeichnet, wie in ImportFilesAsync.

Was Sie in Ihrem Beispiel tun müssen, ist:

  1. Stellen Sie sicher, dass Ihr Programm .Net Framework 4.5 als Target Framework hat.
  2. Markieren Sie Ihre Funktion, die im Ruhezustand sein muss, mit dem Schlüsselwort async (siehe Beispiel unten).
  3. Fügen Sie using System.Threading.Tasks; zu Ihrem Code hinzu.

Ihr Code kann jetzt anstelle der Methode Task.Delay die Methode System.Threading.Thread.Sleep verwenden (await kann für Task.Delay verwendet werden, da Task.Delay in der Definition mit async markiert ist).

private async void button1_Click(object sender, EventArgs e)
{
    textBox1.Text += "\r\nThread Sleeps!";
    await Task.Delay(3000);
    textBox1.Text += "\r\nThread awakens!";
}

Hier können Sie mehr über Task.Delay und Await lesen.

53
Ohlin

Tut mir leid, dass Sie eine alte Frage wie diese geweckt haben. Ich glaube, was der ursprüngliche Autor als Antwort wollte, war:

Sie müssen Ihr Programm dazu zwingen, die Grafik zu aktualisieren, nachdem Sie die Änderung an der Textbox1 vorgenommen haben. Sie können dies tun, indem Sie Update(); aufrufen.

textBox1.Text += "\r\nThread Sleeps!";
textBox1.Update();
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
textBox1.Update();

Normalerweise geschieht dies automatisch, wenn der Thread fertig ist. Ex. Sie drücken eine Taste, Änderungen am Text werden vorgenommen, der Thread stirbt, und dann wird .Update() ausgelöst und Sie sehen die Änderungen kein Experte, also kann ich dir nicht wirklich sagen, wann es abgefeuert wurde, aber es ist sowas irgendwie ähnlich.)

In diesem Fall nehmen Sie eine Änderung vor, unterbrechen den Thread und ändern den Text erneut. Wenn der Thread schließlich beendet ist, wird .Update() ausgelöst. Dies führt dazu, dass Sie nur die letzte Änderung am Text sehen.

Das gleiche Problem tritt auf, wenn Sie zwischen den Textänderungen eine lange Ausführung ausführen.

4
Tomas Frid

Durch Hinzufügen von using System.Timers; zu Ihrem Programm können Sie diese Funktion verwenden:

private static void delay(int Time_delay)
{
   int i=0;
  //  ameTir = new System.Timers.Timer();
    _delayTimer = new System.Timers.Timer();
    _delayTimer.Interval = Time_delay;
    _delayTimer.AutoReset = false; //so that it only calls the method once
    _delayTimer.Elapsed += (s, args) => i = 1;
    _delayTimer.Start();
    while (i == 0) { };
}

Verzögerung ist eine Funktion und kann wie folgt verwendet werden:

delay(5000);
2
user8413784

Sie können wahrscheinlich Timer verwenden: http://msdn.Microsoft.com/de-de/library/system.timers.timer.aspx

Zeitgeber bieten Ihnen eine Genauigkeit von bis zu 1 Millisekunde. Abhängig vom Tick-Intervall wird ein Ereignis generiert. Mach deine Sachen im Tick-Event.

1
Abhishek Shetty
private void WaitNSeconds(int seconds)
{
    if (seconds < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(seconds);
    while (DateTime.Now < _desired) {
         Thread.Sleep(1);
         System.Windows.Forms.Application.DoEvents();
    }
}
0
Khalid