2008-12-18 243 views
0

我有這些容器對象(讓我們稱之爲容器)在列表中。每個Container對象在列表中都有一個DataItem(或派生類)。在典型的情況下,用戶將擁有15-20個容器對象,每個容器對象都有1000-5000個DataItems。然後有一些DataMatcher對象可用於不同類型的搜索。這些工作大部分都很好(因爲我有幾百個單元測試),但爲了讓我的WPF應用程序更加靈活和快速響應,我決定使用ThreadPool來完成此任務。因此,我有一個DataItemCommandRunner它在一個Container對象上運行,並基本上執行列表中的每個委託,它將依次作爲每個DataItem上的參數;我用的是ThreadPool排隊一個線程爲每個容器,這樣在理論上搜索應該是儘可能高效的多核計算機等使用ThreadPools搜索對象列表

這是在DataItemUpdater類,看起來像基本做到了這樣的:

public class DataItemUpdater 
{ 
    private Container ch; 
    private IEnumerable<DataItemCommand> cmds; 

    public DataItemUpdater(Container container, IEnumerable<DataItemCommand> commandList) 
    { 
     ch = container; 
     cmds = commandList; 
    } 

    public void RunCommandsOnContainer(object useless) 
    { 
     Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; 
     foreach (DataItem di in ch.ItemList) 
     { 
      foreach (var cmd in cmds) 
      { 
       cmd(sh); 
      } 
     } 
     //Console.WriteLine("Done running for {0}", ch.DisplayName); 
    } 
} 

(用於RunCommandsOnContainer無用的對象參數是因爲我這個實驗使用和不使用線程,而其中一個需要一些參數的同時,優先級設置爲AboveNormal只是一個實驗a一報還一)

也能正常工作,但所有一個場景 - 當我使用AllWordsMatcher對象類型,將查找正在搜索包含的所有單詞DataItem對象(而不是任何話,確切的短語或例如正則表達式)。

這是一個非常簡單的somestring.Contains(eachWord)基於對象,由單元測試支持。但這裏有一些毛茸茸的陌生。

RunCommandsOnContainer使用ThreadPool線程運行時,它將返回瘋狂的結果。說我有一個像這樣的字符串:

var someString = "123123123 - just some numbers"; 

我運行此:

var res = someString.Contains("data"); 

當它運行時,這實際上將返回true頗多 - 我已經調試,顯示其返回的真實信息空字符串和其他不包含數據的字符串。而且,即使字符串實際上包含要查找的數據,它也會返回錯誤。

在這一切的踢球?爲什麼我懷疑ThreadPool而不是我自己的代碼?

當我在主線程中爲每個容器運行RunCommandsOnContainer()命令(即鎖定UI和所有內容)時,它每次都能正確工作!它永遠找不到它不應該的東西,它永遠不會跳過它應該找到的任何東西。

但是,只要我使用ThreadPool,它就會開始找到很多項目它不應該,但有些時候找不到它應該的項目。

我意識到這是一個複雜的問題(嘗試調試是痛苦的,這是肯定的!),但任何深入瞭解爲什麼以及如何解決這個問題將不勝感激!

謝謝!

符文

回答

2

這是一個有點硬從您發佈的片段見到,但症狀我會看看AllWordsMatcher(查找靜態)判斷。如果AllWordsMatcher是有狀態的,您還應該檢查是否爲每個線程創建了一個新實例。

更一般地說,我會看看匹配/搜索過程中涉及的所有實例,特別是多線程時使用的工作對象。從過去的經驗來看,問題通常就在那裏。 (在這種情況下,很容易看到表示業務數據容器/數據項的對象圖)

+0

您來得足夠近以至於我發現它 - 它本身不是靜態,而是一個類級變量在實例之間共享。愚蠢,愚蠢的錯誤,現在已經修復。謝謝一堆! – 2008-12-18 17:57:59