2017-04-11 1 views
0

Ich habe ein Programm, das prüft, was die Benutzerreaktionszeit ist, basierend auf der Geschwindigkeit, die er auf die Schaltfläche klickt, wenn es grün wechselt. Ich möchte die Funktion, die nach dem Klicken der Schaltfläche funktioniert, im Hintergrund ausführen.Wie man Knopfbetrieb im Hintergrund macht

Ich habe zwar mit Task, es wird es asynchron machen, aber es scheint nicht der Fall zu sein. Ich verstehe, dass es ein Warten gibt und wahrscheinlich sollte ich es irgendwie dorthin zurückbringen, wo es hieß, aber ich habe ein Problem, die Lösung zu finden.

Mein Code so sieht weit wie diese

public partial class Reaction : Form 
{ 
    Stopwatch timer; 
    bool start = false; 
    public Reaction() 
    { 
     InitializeComponent(); 
     button1.Text = "START"; 
     button1.BackColor = Color.Red; 

    } 

    public async Task Test() 
    { 
     if (start) 
     { 
      timer.Stop(); 
      TimeSpan timespan = timer.Elapsed; 
      string timeString = String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds/10); 
      MessageBox.Show(timeString); 
      button1.BackColor = Color.Red; 
      button1.Text = "START"; 
      start = false; 
     } 
     else 
     { 
      Random rnd = new Random(); 
      int number = rnd.Next(1, 10000); 
      System.Threading.Thread.Sleep(3000 + number); 
      timer = Stopwatch.StartNew(); 
      button1.BackColor = Color.Green; 
      button1.Text = "CLICK"; 
      start = true; 
     } 
    } 

    private async void button1_Click(object sender, EventArgs e) 
    { 

     button1.BackColor = Color.Red; 
     button1.Text = "Dont click"; 
     await Test(); 
    } 
} 
+0

Warum führen Sie nicht den "Hintergrund" Code in einem neuen Thread? So: Thread T = neuer Thread (Test); T.start(); – Taco2

+1

sollten Sie Task.Delay (1000); statt Thread .Schlaf –

+0

Usin g Aufgabe.Delay (1000); löst das Problem nicht. Es ist nur noch ein Warten auf "Warten" – Taco2

Antwort

0

auf den Kommentaren Basierend ich die Post bearbeiten mehr zu reflektieren genau, was Sie fragen. Entfernen Sie die async und warten Sie im click-Ereignis der Schaltfläche und ersetzen Sie das System.Threading.Thread.Sleep (... mit warten Task.Delay (...) So müssen Sie nicht BeginInvoke auf button1 und das einzige, was auf a separater Thread wird die Task.Delay (...

die Benutzeroberfläche wird sich während der Task.Delay (... und dann reagiert wieder aufnehmen, wo sie aufgehört hat, wenn die Verzögerung beendet ist.

public partial class Reaction : Form 
{ 
    Stopwatch timer; 
    bool start = false; 
    public Reaction() 
    { 
     ... 
    } 

    public async Task Test() 
    { 
     if (start) 
     { 
      ... 
     } 
     else 
     { 
      Random rnd = new Random(); 
      int number = rnd.Next(1, 10000); 

      // Replace Thread.Sleep with Task.Delay 
      await Task.Delay(3000 + number); 

      timer = Stopwatch.StartNew(); 
      button1.BackColor = Color.Green; 
      button1.Text = "CLICK"; 
      start = true; 
     } 
    } 

    // Make button1_Click not async and remove await 
    private void button1_Click(object sender, EventArgs e) 
    { 
     button1.BackColor = Color.Red; 
     button1.Text = "Dont click"; 
     Test(); 
    } 
} 
+0

beim Ändern der Schaltfläche Text in button1.Text = "CLICK"; Ich bekomme einen Zugriff von verschiedenen Thread-Fehler – feni000

+1

@ feni000: ja, Sie tun. Weil die obige Antwort nur Ihren ursprünglichen Code enthält und ihn in ein ganz neues Problem bringt. Sie brauchen 'Task.Run()' hier nicht. Sie benötigen 'aware Task.Delay()' in Ihrer ursprünglichen Methode oder fügen Sie einfach diesen ganzen Code in die 'button1_Click()' Methode ein. –

+0

Obwohl dies funktionieren könnte, bietet 'async/await' eine elegantere Lösung ohne die Notwendigkeit von' Task.Run', wie @PeterDuniho erwähnt wurde. –

Verwandte Themen