2012-11-15 77 views
19

我有一個控制檯應用程序,我想保持打開所有的時間,同時仍然收聽事件。我已經測試了Thread.Sleep(Timeout.Infinite);while (true) { },並且都允許在保持控制檯應用程序打開的情況下引發事件。有沒有我應該使用的另一個?如果線程正在休眠,是否有任何我不應該做的事情,比如修改在類範圍內聲明的靜態集合?是Thread.Sleep(Timeout.Infinite);比while(true){}更高效?

回答

22

我會建議使用ManualResetEvent(或其他WaitHandle),並調用ManualResetEvent.WaitOne

這將產生類似的效果永遠沉睡,只是在需要時(通過調用事件Set()),它爲您提供一個乾淨的方式從你的無限「塊」 退出

使用while(true)會消耗CPU週期,所以這絕對是要避免的。

有什麼我不該做的,比如修改一個在類範圍內聲明的靜態集合?

一般來說,沒有。由於您的線程將被阻止,因此使用共享數據時不應存在任何同步問題(前提是集合中的項目沒有特定要求,例如必須在具有適當同步上下文的線程上使用的用戶界面元素。)

+0

我實際上不希望它退出,但我會接受你的回答,以防有人看起來希望有辦法退出。 – Lunyx

+0

@Daniel它是好的,有一個乾淨的方式爲你的程序關機* *最後,即便這不是你想要在任何時間點的具體的東西;)話雖這麼說,我還是會使用這種方法了一覺,親自。 –

+0

會如何使用使用ManualResetEvent的使用Thread.sleep()方法不同,如果該程序將關閉唯一的一次是在機器重新啓動時? – Lunyx

4

while(true)...不同,Thread.Sleep不使用CPU週期,所以從這個意義上講,睡眠效率更高。一般來說,在spinlocks之外使用Busy Waiting是非常不鼓勵的。

如果線程在睡覺,有什麼我不應該做的?

由於您的線程在進入Thread.Sleep時被阻止,您希望對其資源執行的任何操作都是公平的遊戲。

+0

謝謝,我已經看到了被推薦的人試圖完成我在做什麼,while循環,我不知道這是否是去了解它的正確方法。 – Lunyx

2

while(true)消耗CPU而sleep()作品以更聰明的方式: 的sleep()功能把睡覺當前執行上下文;它通過調用系統調用來調用內核睡眠功能,其原子
的(a)設置一個喚醒定時器執行此
(b)中標記當前過程昏睡
(c)中等待,直到喚醒定時器火災或發生中斷

如果您致電sleep(),則CPU可以執行其他工作。

這就是爲什麼sleep()有用的原因之一。

一個有用的鏈接 - Be careful when using Sleep

3

我認爲呼叫

while (true) { ... } 

是計算密集型的,因爲線程永遠不會停止,wheareas

Thread.Sleep(Timeout.Infinite); 

實際獲得的線程與OS本地調度幫助入睡。然後線程實際上停止了,所以我認爲它的計算要求不高。

+2

你的答案似乎有些不確定......「我認爲」,「我想」等等。 –

+0

我確信這個答案,但是我剛剛開始了java的職業生涯,這就是爲什麼我用「我認爲」,「我想「爲了預防。 :) – leoismyname