2009-02-16 87 views
2

TL; DR版本:我有兩個線程。其中一個可能需要Interrupt()另一個,但只有當另一個線程處於處理與受第一個線程影響的對象相關的數據的中間時。我怎樣才能根據某些條件中斷()第二個線程。如何同步這些線程以避免數據損壞?

我一直在研究一個程序,該程序可以處理套接字數據並更新GUI的信息。兩個線程(topologyThread和dataThread)處理我的應用程序的兩個不同方面,即我們無線傳感器網絡的拓撲變化通知,以及用於接收和處理來自無線傳感器網絡的數據的數據信息。

當數據進入dataThread時,數據包所代表的網絡成員可能已經被topologyThread移除了,因此不應該被處理。所以,我一直在想,使用Thread.Interrupt()方法可以讓我立即通知dataThread拓撲結構的變化,並且防止我們在嘗試用一個網絡成員的數據更新GUI時遇到的一些問題不再連接。我的問題是:如何判斷dataThread是否需要中斷?我不希望它在處理仍然連接的網絡成員的數據時拋出異常,但是如果它處於處理斷開連接的網絡成員的數據的過程中,我希望它被中斷。

方案1:

  • 數據來自在dataThread。
  • dataThread確保網絡成員仍然是網絡的一部分。
  • dataThread處理數據到端部和更新GUI

方案2:

  • 數據來自在上dataThread。
  • dataThread確保網絡成員仍然是網絡的一部分。
  • 網絡成員已斷開連接,因此不進行處理。

方案3:

  • 數據來自在dataThread。
  • dataThread確保網絡成員仍然是網絡的一部分。
  • dataThread開始處理數據
  • topologyThread接收到網絡成員已斷開連接並將其從拓撲中刪除的通知。
  • dataThread嘗試更新不再連接的網絡成員的GUI。

這是我試圖編寫的場景3。在我們的測試中,這種情況是側欄中的樹視圖凍結並且應用程序必須被終止的地方。但是,如果受到topologyThread影響的對象是dataThread當前正在處理的對象,那麼我只需要中斷dataThread。

感謝您的閱讀。 :)

回答

1

dataThread嘗試爲一個不再連接的網絡成員更新GUI。

如果在網絡成員不再連接時有拓撲線程設置標誌並且在嘗試更新GUI之前讓dataThread檢查該標誌,該怎麼辦?

+0

我與此類似的解決方案。如果在拓撲線程嘗試刪除它時,dataThread正在處理特定的網絡成員,則拓撲線程將等待,直到該標記爲空,然後再從拓撲中刪除它。 – jxpx777 2009-02-20 15:43:02

2

你不應該打斷你的線程。使用EventWaitHandles對它們進行編程可能會比較安全,它可以根據您嘗試實現的目標來觸發信號。

+0

EventWaitHandles只有在他試圖阻止的線程沒有做任何事情時纔有用。如果它被阻塞等待從網絡套接字讀取,該怎麼辦? Interrupt()在這裏適用。 – bobwienholt 2009-02-16 16:06:46

0

Interrupt()只在線程被阻塞時才能工作...所以你需要有另一種機制來停止處理。如果您有一個正在處理數據的循環,最好的方法是創建一個變量,以便在處理完成後終止處理。

這是我會怎麼做呢?

Thread dataThread; 
bool continueProcessing = true; 
String currentNetworkMember = ""; 

public NotifyMemberRemoved(String member) 
{ 
    if (currentNetworkMember == member) 
    { 
     continueProcessing = false; 
     // Incase the thread is blocked... 
     dataThread.Interrupt(); 
    } 
} 

public void ProcessingLoop() 
{ 
    while (true) 
    { 
     currentNetworkMember = GetMemberToProcess(); 
     continueProcessing = true; 
     while (continueProcessing) 
     { 
      try 
      { 
       // Process data... 
       ReadDataChunk(); 
       ProcessDataChunk(); 
      } 
      catch (InterruptedException e) 
      { 
       // Whatever interrupted us must have set continueProcessing to false... 
      } 
     } 
     UpdateGUI(); 
    } 
} 
0

基本版本。加強以滿足您的需求。

public class CancellationInfo { 
    bool _Cancel = false; 
    bool _Sync = new object(); 
    public bool Requested { get { lock(_Sync) { return _Cancel; } } 
    public void Request() { lock(_Sync) _Cancel = true; } 
} 

public class ThreadActions { 
    private CancellationInfo Cancel = new CancellationInfo; 
    public void FirstThreadAction() { 
     while(true) { 
      //Process some stuff. 
      if(condition) 
       Cancel.Request(); 
     } 
    } 
    public SecondThreadAction() { 
     while(true) { 
      if(Cancel.Requested) 
       break; 
      //Process some stuff. 
     } 
    } 
}