0

我在一个列表中有这些容器对象(我们称它们为容器)。这些 Container 对象中的每一个又DataItem在列表中具有一个(或派生类)。在典型场景中,用户将拥有 15-20 个 Container 对象,每个对象有 1000-5000DataItems个。然后有一些DataMatcher对象可用于不同类型的搜索。这些工作大部分都很好(因为我对它们进行了数百个单元测试),但为了让我的 WPF 应用程序感觉敏捷和响应,我决定我应该使用ThreadPool这个任务。因此,我有一个在 Container 对象上运行的DataItemCommandRunner,并且基本上在列表中执行每个委托,它DataItem依次作为每个委托的参数;我用ThreadPool为每个 Container 排队一个线程,这样理论上搜索在多核计算机等上应该尽可能高效。

这基本上是在一个看起来像这样的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也只是一个实验。)

这适用于除一种情况外的所有情况 - 当我使用将查找包含所有正在搜索的单词的对象的AllWordsMatcher对象类型时(而不是任何单词,例如确切的短语或正则表达式)。DataItem

这是一个非常简单somestring.Contains(eachWord)的基于对象,由单元测试支持。但这里有一些毛茸茸的奇怪。

RunCommandsOnContainer使用ThreadPool线程运行时,它将返回疯狂的结果。假设我有一个这样的字符串:

var someString = "123123123 - just some numbers";

我运行这个:

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

当它运行时,这实际上会返回很多 true - 我有调试信息显示它对于空字符串和其他根本不包含数据的字符串返回 true。此外,即使字符串实际上包含正在查找的数据,它有时也会返回 false。

在这一切的踢球者?为什么我怀疑ThreadPool而不是我自己的代码?

当我为我的主线程中的每个容器运行RunCommandsOnContainer()命令时(即锁定 UI 和所有内容),它可以 100% 正确运行 - 每次!它永远不会找到它不应该找到的任何东西,它永远不会跳过它应该找到的任何东西。

但是,一旦我使用ThreadPool,它就会开始找到很多它不应该找到的项目,而有时却找不到它应该找到的项目。

我意识到这是一个复杂的问题(尝试调试很痛苦,这是肯定的!),但是任何关于为什么以及如何解决这个问题的见解将不胜感激!

谢谢!

符文

4

1 回答 1

2

从您发布的片段中很难看出,但从症状来看,我会查看 AllWordsMatcher (查找静态状态)。如果 AllWordsMatcher 是有状态的,您还应该检查您是否正在为每个线程创建一个新实例。

更一般地说,我会查看匹配/搜索过程中涉及的所有实例,特别是多线程时使用的工作对象。从过去的经验来看,问题通常出在那儿。(在这种情况下,很容易看太多表示您的业务数据Container/DataItem 的对象图)

于 2008-12-18T06:30:52.003 回答