2012-12-09 111 views
0

當表單被加載時myMethod()被調用,然後它執行一些語句。在它到達if語句的某一時刻,它應該停止並等待用戶按下某個按鈕,然後根據用戶的操作繼續執行。我使用Thread.Sleep()和ManualResetEvent obj的WaitOne()方法,但它們似乎凍結了整個過程,直到時間到期才能完成任何操作。我認爲KeyEventHandler應該在後臺運行,所以它永遠不會受到影響......無論如何,我該怎麼做?等待用戶響應

public partial class Form1 : Form 
{ 
    bool pressed = false; 
    public Form1() 
    { 
     InitializeComponent(); 
     this.KeyPreview = true; 
     this.KeyDown +=new KeyEventHandler(Form1_KeyDown); 
    } 

    void Form1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.E) 
     { 
      pressed = true; 
     } 
    } 

    void myMethod() 
    { 
     while (someBool) 
     { 
      //do something 
      if (pressed) 
      //do this 
      else 
      //do that 
     } 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     myMethod(); 
    } 
} 
+0

也許你想在單獨的線程上運行'myMethod()',或者你想重新考慮你的設計。爲什麼不把「myMethod()」的相關部分放在按鍵事件處理程序中? – neeKo

+0

如果我把myMethod()的一部分放在按鍵事件處理程序用戶需要時間按下右鍵?但是當myMethod被執行時,程序不能捕獲被按下的鍵,除非它在不同的線程上被執行 –

+0

把myMethod的第一部分('//做某事')放到'Form_Load'中,放第二部分('//做這個')在'if(e.KeyCode == Keys.E)'中,把第三部分('// do that')放到'else'中。 – neeKo

回答

0

開始嘗試你的方法爲Task

private void Form1_Load(object sender, EventArgs e) 
{ 
    System.Threading.Tasks.Task t = new Task(() => myMethod()); 
    t.Start(); 
} 

當你測試你的方法pressed,將其設置爲false

void myMethod() 
{ 
    while (someBool) 
    { 
     //do something 
     if (pressed) 
     { 
      pressed = false; 
      //do this 
     } 
     else 
     //do that 
    } 
} 

當然,這也可能導致一多種多線程錯誤,取決於您在myMethod()中的實際操作。我建議您在開始使用多個線程之前先查看thread synchronization

0

你攻擊這個問題的方式並不好,因爲你在等待用戶輸入時不應該阻塞GUI線程。你應該做任何你能做的事情,然後立即返回,以便GUI線程可以處理消息。

  • 在Form1_Load上,運行myMethod(),您可以在其中「執行某些操作」(初始化),然後立即返回。不要在這裏阻止。
  • 在KeyDown事件中,如果E被按下,您可以「執行此操作」。這部分應該很容易。
  • 我想知道什麼時候需要「這樣做」才能運行(即沒有按下按鍵),我有點困惑。你能否澄清這種情況何時發生?
+0

正如我在最後的評論中提到的,myMethod()在while循環中有它。如果沒有按下鍵,則應該執行「這樣做」。 –

0

添加定時器組件到表單中並設置它要等待用戶輸入間隔時間(毫秒):

bool someBool = true; 

public Form1() 
{ 
    InitializeComponent(); 
    KeyPreview = true; 
    timer1.Interval = 1000; 
} 
的形式負載

啓動計時器:

private void Form1_Load(object sender, EventArgs e) 
{ 
    timer1.Start(); 
} 

添加定時器Tick事件處理程序如果用戶在指定的等待超時(timer1.Interval)期間未按任何鍵,則會觸發此事件。

private void timer1_Tick(object sender, EventArgs e) 
{ 
    if (someBool)  
     //do that 
    else 
     timer1.Stop();  
} 

在KeyDown事件處理程序停止計時,然後處理按鍵,並啓動定時器等待下一個用戶輸入(或do that如果沒有輸入):另外本次活動將定期,而不是你的while環募集:

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{ 
    timer1.Stop(); 
    if (!someBool) 
     return; 

    if (e.KeyCode == Keys.E) 
     // do this 
    else 
     // do that 

    timer1.Start(); 
}