0

リストにこれらのコンテナー オブジェクト (コンテナーと呼びましょう) があります。これらの Container オブジェクトのそれぞれはDataItem、リストに (または派生物) を順番に持っています。典型的なシナリオでは、ユーザーはDataItemsそれぞれ 1000 から 5000 の 15 から 20 のコンテナ オブジェクトを持っています。DataMatcher次に、さまざまなタイプの検索に使用できるオブジェクトがいくつかあります。これらはほとんど問題なく動作します (数百の単体テストがあるため) が、WPF アプリケーションを機敏で応答性の高いものにするために、ThreadPoolこのタスクには を使用することにしました。したがって、Container オブジェクトで実行されるDataItemCommandRunnerがあり、基本的に、リスト内の各デリゲートを、それぞれのパラメーターとしてDataItem順番に実行します。私はThreadPoolコンテナごとに 1 つのスレッドをキューに入れることで、マルチコア コンピュータなどで理論上の検索が可能な限り効率的になるようにします。

これは基本的に、次のような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の役に立たないオブジェクト パラメーターは、スレッドを使用して、またはスレッドを使用せずにこれを実験しているためであり、そのうちの 1 つにはパラメーターが必要です。また、優先度をAboveNormalに設定することも単なる実験です。)

これは、検索対象のすべての単語を含むオブジェクトをAllWordsMatcher検索するオブジェクト タイプを使用する場合DataItem(任意の単語、正確なフレーズ、または正規表現とは対照的に)、1 つのシナリオを除くすべてのシナリオで正常に機能します。

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 に答える