2017-04-11 57 views
0

我有一個程序,當它變成綠色時,它會根據按鈕上點擊按鈕的速度來檢查用戶反應時間。我希望點擊按鈕後在後臺運行的功能。如何在後臺執行按鈕運行操作

我雖然通過使用任務它會使它異步,但它似乎並非如此。我知道有一個等待,可能我應該讓它返回到它被稱爲的地方,但我有一個問題找到解決方案。

到目前爲止我的代碼看起來像這樣

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

爲什麼不要在新線程中運行「背景」代碼像這樣: 線程T =新線程(測試); T.start(); – Taco2

+1

您應該使用Task.Delay(1000);而不是Thread 。睡眠 –

+0

Usin g Task.Delay(1000);並不能解決問題。這只是等待「等待」 – Taco2

回答

0
基於我編輯的職位,以反映你問的更密切什麼意見

。刪除按鈕的單擊事件中的異步和等待,並替換System.Threading.Thread.Sleep(...與等待Task.Delay(...這樣你就不必使用button1上的BeginInvoke,並且唯一的單獨的線程將是Task.Delay(...

的UI將在Task.Delay(期間成爲響應...,然後繼續在那裏當延遲完成它不放過。

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

,同時更改button1.Text中的按鈕文本=「CLICK」;我從不同的線程錯誤 – feni000

+1

@ feni000得到一個訪問:是的,你這樣做。因爲上面的答案只是把你的原始代碼包裝在一個全新的問題中。這裏不需要'Task.Run()'。您需要在原始方法中等待Task.Delay(),或者將所有代碼放在'button1_Click()'方法中。 –

+0

儘管這可以起作用,但async/await提供了更優雅的解決方案,無需像@PeterDuniho提到的那樣需要Task.Run。 –

相關問題