2013-08-22 29 views
19

我對編程非常陌生,我認爲迄今爲止我的學習已經足夠好了,但我仍然無法理解按照我想要的方式進行延遲的想法。我正在使用的是一種使用涉及戰鬥系統的Windows窗體應用程序的測試「遊戲」。其中,我想讓NPC每隔幾秒做一次動作。問題是,我也想讓玩家在各種攻擊之間進行互動。真正的Thread.sleep似乎並沒有爲我工作,不僅是因爲我不知道該如何多線程,但每當我嘗試運行它,比方說,像這樣的:如何在不使用睡眠的情況下在C#中執行短暫延遲?

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

這似乎堅持睡覺首先,然後打印兩條線。

我認爲這就是我現在可以說的,但如果這仍然太模糊或羅嗦,隨時告訴我。

總之,在C#中,我希望在運行之前做一些延遲,但同時仍然允許用戶交互。

+1

可以使用定時器來代替,而火了在你的間隔... – Rohit

+0

該線程也負責打印你的用戶界面,但由於你使用'睡眠'來阻止它,它不能更新顯示你的第一行的用戶界面。 – user2674389

+0

使用Task.Delay而不是睡眠。那麼你將不會有任何阻止用戶界面的問題。這個新功能可以在.Net 4.5中找到。 – Ohlin

回答

47

如果您使用.NET 4.5,則可以使用新的異步/等待框架進行睡眠而不鎖定線程。

它的工作原理是用async關鍵字標記需要異步操作的函數。這只是編譯器的一個提示。然後在想要代碼異步運行的行上使用await關鍵字,並且程序將等待而不鎖定線程或UI。您調用的方法(在await行上)必須標有async關鍵字,並且通常以Async結尾,如ImportFilesAsync

你需要在你的例子做的是:

  1. 確保你的程序有.Net框架4.5目標框架
  2. 標記您的功能需要與async關鍵字睡覺(請參閱下面的示例)
  3. using System.Threading.Tasks;添加到您的代碼中。

你的代碼現在準備使用Task.Delay方法,而不是System.Threading.Thread.Sleep方法(也可以在Task.Delay使用await因爲Task.Delay在其定義標記async)。

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

在這裏,你可以閱讀更多有關Task.DelayAwait

+0

「await」後面的所有代碼都會異步運行嗎?我用兩個複選框做了一個例子,似乎是這樣。 – Black

+0

@黑色你只能在標記爲「async」的函數上使用'await',所以是的 - 它將始終是異步的。 – Ohlin

+0

但只有等待後的部分? – Black

4

對不起,喚醒這樣的老問題。 但我認爲原作者想要的答案是:

在對textbox1進行更改後,您需要強制程序進行圖形更新。你可以做到這一點通過調用Update();

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

通常這會自動完成,當線程完成。 例如,您按下按鈕,對文本進行更改,線程將死掉,然後啓動.Update(),您會看到更改。 (我不是專家,所以我不能真正告訴你它什麼時候被解僱,但是它有類似於此的任何方式。)

在這種情況下,您進行更改,暫停該線程,然後更改文本再次,當線程最終死亡時,.Update()被解僱。這導致您只能看到文本的最後更改。

如果您在文本更改之間執行很長時間,則會遇到同樣的問題。

0
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

通過添加using System.Timers;你的程序,你可以使用此功能:

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

延遲是一個函數,可以使用這樣的:

delay(5000); 
相關問題