我有這些容器對象(讓我們稱之爲容器)在列表中。每個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
,它就會開始找到很多項目它不應該,但有些時候找不到它應該的項目。
我意識到這是一個複雜的問題(嘗試調試是痛苦的,這是肯定的!),但任何深入瞭解爲什麼以及如何解決這個問題將不勝感激!
謝謝!
符文
您來得足夠近以至於我發現它 - 它本身不是靜態,而是一個類級變量在實例之間共享。愚蠢,愚蠢的錯誤,現在已經修復。謝謝一堆! – 2008-12-18 17:57:59