2014-03-19 61 views
0

我正在開發一個應用程序,它定期輪詢Web服務的一些數據。應用程序必須作爲Windows服務運行,因此必須以異步方式啓動和停止。我爲此使用了線程。什麼是更好的方法來阻止這個工作者線程?

工作線程的主循環的作用是這樣的:

bool stop = false; 
int interval = 60000; // 60 seconds, customizable 

while(!stop) 
{ 
    try 
    { 
     // Query the web service using a WebRequest 
    } 
    catch(Exception e) 
    { 
     // Handle exception 
    } 

    // Process data 

    try 
    { 
     Thread.Sleep(interval); 
    } 
    catch(ThreadInterruptedException) 
    {} 
} 

要停止工作線程,我這樣做是從控制線程:

stop = true; 
workerthread.Interrupt(); 
workerthread.Join(); 

這工作完全...除非偶然的情況是,當調用Thread.Interrupt()時,工作線程恰好正在執行(或尚未執行)web請求;在這種情況下,實際中斷的是web請求(大概是自己睡覺),並且下一個Sleep()必須等到它的正常超時退出。

什麼是更好的方法來實現這一點,並避免在錯誤的地方中斷工作線程?

+0

如果您的所有服務都是睡眠並定期輪詢,那麼它應該是計劃任務而不是服務。請參閱[程序不是貓](http://blog.mischel.com/2013/02/01/programs-are-not-cats/)。 –

回答

2

使用MaualResetEvent

在類啓動線程:

ManualResetEvent evt = new ManualResetEvent(false); 

然後修改代碼爲:

int interval = 60000; // 60 seconds, customizable 

while(evt.WaitOne(interval)) 
{ 
    try 
    { 
     // Query the web service using a WebRequest 
    } 
    catch(Exception e) 
    { 
     // Handle exception 
    } 

    // Process data 
} 

停止線程,只需調用evt.Set();

這會導致線程甚至停止如果是在60秒的中間等待。

+1

如果工作線程在調用'evt.Set()'時沒有等待會發生什麼? – Massimo

+0

下次碰到while循環的頂部時,它會立即停止。您的流程的每個循環是否需要很長時間? – pquest

+0

不,最多幾秒鐘;可以完成運行循環並在到達下一個WaitOne()時退出。 – Massimo

相關問題