2008-12-18 253 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