2010-09-30 50 views
1

這是一個兩部分的問題。從另一個線程處理線程執行的可能方法?

首先,讓我們說,我有一個是在另一個線程執行的函數:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    a(); 
    b(); 
    c(); 
    } 
} 

現在我想暫停這個線程。 Thread.Suspend是不可能的,因爲在調用它之後,它不能保證我沒有死鎖系統。等待另一個AutoResetEvent也是不希望的,因爲暫停「粒度」會太大。我想出了兩個「解決方案」,但我不激動不已要麼他們(但#2此刻正優先)的:

1)交錯PauseEvent.WaitOne()無處不在:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 
private ManualResetEvent PauseEvent = new ManualResetEvent(true); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    PauseEvent.WaitOne(0); 
    a(); 
    PauseEvent.WaitOne(0); 
    b(); 
    PauseEvent.WaitOne(0); 
    c(); 
    } 
} 

2)強制(),b()和c()來拋出MyException。然後,我可以在catch塊等到「恢復」按鈕,點擊信號PauseEvent:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 
private AutoResetEvent PauseEvent = new AutoResetEvent(false); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    try { 
     a(); 
     b(); 
     c(); 
    } catch(MyException) { 
     PauseEvent.WaitOne(); // wait indefinitely until signaled by another thread 
    } 
    } 
} 

(2)真的好像要做到這一點的唯一方法,但我想知道是否有人已經嘗試另一個「暫停」的方法。

其次,我得到絆倒的部分是解決方案#2誘導異常的好方法。目前,我已經基本上安裝了由a(),b()和c()調用的低級代碼來查找要發送信號的事件,以告訴它們拋出MyException。這是我知道的唯一方法,你可以在另一個線程上誘發行爲。

我倒是真的想知道的是(我敢肯定這是不可能的),有沒有在.NET中一些瘋狂的方式,使一個工人線程註冊事件處理程序,所以,當我火來自我的GUI的事件,工作線程立即停止它正在執行的操作並執行處理程序?我想我基本上是在尋找像中斷服務程序那樣的東西,就像你通常在微控制器上實現的那樣。

回答

0

在解決了這個問題的幾種不同方法之後,我認爲我有一些工作得很好。我基本上與#2一起,因爲它利用AutoResetEvent的基本行爲來暫停和恢復。

我的線程運行從無狀態派生的狀態機,所以我能夠將所有暫停和恢復功能放在基類中,這使得我的代碼更加乾淨。我還可以通過重寫派生類中的方法來獲得客戶端特定的功能。最後,在代碼的粒度和代碼的優雅之間進行了權衡。我犧牲了粒度,所以我不必在任何地方胡椒WaitOne()

0

我不知道在.Net中具有優先級中斷的微控制器風格的方法。但在此期間,您可能需要考慮一個共享標誌,您的線程會不斷檢查它是否應暫停或運行。一旦檢測到暫停請求,它就可以使用Thread.SleepTimer來檢查是否允許運行。也許不像你所期望的那樣優雅,但它是可預測和易於實現的。

+0

標誌方法基本上是我上面的第一個實現。可以肯定的是,這可能是唯一的方法。我今天正在開發實施#2,但是它在系統中有自己的奇特行爲。 – Dave 2010-10-01 06:10:08

相關問題