2010-06-28 49 views
2

因此出現了一個新問題...C#多線程代理檢查器

我在c#中編寫了一個多線程代理檢查器。

我正在使用BackgroundWorkers解決多線程問題。

但我有問題協調和分配隊列中的代理隊列中的運行工人。它大部分時間都在工作,但有時候沒有結果返回,所以一些代理在這個過程中會「失去」。

該列表表示隊列,並在ListView中填充了proxys的id。

private List<int> queue = new List<int>(); 

private int GetNextinQueue() 
    { 
     if(queue.Count > 0) 
     { 
      lock (lockqueue) 
      { 
       int temp = queue[0]; 
       queue.Remove(temp); 
       return temp; 
      } 
     } 
     else 
      return -1; 
    } 

以上就是我的方法來獲得在隊列中的下一個代理,我使用的lock語句來防止競爭條件,但我不確定它是否足夠,或者是否下降減緩的過程,因爲它使其他線程等待... (lockqueue是一個對象只是用於鎖定)

所以我的問題是,怎麼可能有些代理沒有得到檢查(即使ping失敗檢查應該返回的東西,但有時theres什麼都沒有)以及我如何優化此代碼的性能?

下面是我對這個問題http://pastebin.com/iJduX82b

認爲重要的,如果缺了點什麼就寫評論

謝謝:)

回答

1

如果你有興趣在古樸典雅,使用隊列:

private Queue<int> queue = new Queue<int>(); 
    private int GetNextinQueue() 
    { 
     lock (queue) { return queue.Count > 0 ? queue.Dequeue() : -1; } 
    } 
+0

謝謝,非常漂亮的解決方案。 並感謝所有其他人的幫助,我非常感謝,但很遺憾,我只能接受一個答案。 現在我認爲「代理失敗」的問題已經解決。 – Chilln 2010-06-29 16:04:20

2

幾件事情的其餘代碼:

  1. queue字段的所有訪問需要進入lock (lockqueue)塊 - 其中包括if (queue.Count > 0)以上。這不是性能問題:如果您沒有獲取必要的鎖,您的應用程序將無法工作。

  2. 從您的pastebin,致電RunWorkerAsync看起來很可疑。目前每個BackgroundWorker共享相同的參數數組;你需要給每一個自己的副本。

4

queue.Count的檢查應該在鎖定語句中執行。 Otberwise你可以檢查queue.Count> 0,但是當你能夠輸入鎖時,另一個線程可能已經從隊列中刪除了一個項目,然後你將在可能爲空的隊列中調用Remove。

你可以將它修改爲:

private int GetNextinQueue() 
    { 
     lock (lockqueue) 
     { 
      if(queue.Count > 0) 
      { 
       int temp = queue[0]; 
       queue.Remove(temp); 
       return temp; 
      } 
      else 
       return -1; 
     } 
    } 

基本上,如果你想守護訪問與鎖的數據結構,確保您防護所有的讀取和寫入該結構線程安全。

2

試試這個:

private int GetNextinQueue() 
{ 
    int ret = -1; 
    lock (queue) 
    { 
     if (queue.Count > 0) 
     { 
      int temp = queue[0]; 
      queue.Remove(temp); 
      ret = temp; 
     } 
    } 
    return ret; 
} 

我不會擔心這個性能 - 這是真的,如果一個線程持有鎖,但是從列表中刪除的int沒有其他線程將在這裏封鎖需要很長時間。

此外,您並不需要lockqueue對象 - 因爲queue是要鎖定訪問權限的對象,請使用它。

+1

「還有,你並不真的需要一個lockqueue對象 - 因爲隊列是要鎖定的對象的訪問,只是使用它。」 - 不要這樣做;改爲鎖定一個單獨的「對象」實例。這是對其他可能在內部使用'lock(this)'的類作者的防禦。 – 2010-06-28 12:34:17

+0

@Tim Robinson:'lock(this)'會被認爲是不好的編程習慣(http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx),我懷疑作者'List'可以做到這一點。 – MusiGenesis 2010-06-28 14:33:36

+0

來自MSDN的更多信息:「嚴格來說,提供給鎖的對象僅用於唯一標識多個線程之間共享的資源,因此它可以是任意的類實例。但實際上,該對象通常表示資源線程同步是必要的。「 – MusiGenesis 2010-06-28 14:37:25