Question

J'ai ces objets conteneurs (appelons-les conteneurs) dans une liste. Chacun de ces objets conteneurs à son tour une DataItem (ou un dérivé) dans une liste. Dans un scénario typique d'un utilisateur aura 15-20 objets conteneurs avec 1000-5000 DataItems chacun. Ensuite, il y a des objets DataMatcher qui peuvent être utilisés pour différents types de recherches. Ces travaux surtout bien (depuis que j'ai plusieurs centaines de tests unitaires sur eux), mais pour faire mon application WPF sentir accrocheurs et réactif, j'ai décidé que je devrais utiliser le ThreadPool pour cette tâche. Ainsi je DataItemCommandRunner qui fonctionne sur un objet conteneur, et effectue essentiellement chaque délégué dans une liste, il prend comme un paramètre sur chaque DataItem à son tour; J'utilise le ThreadPool à faire la queue un fil pour chaque conteneur, de sorte que la recherche en théorie devrait être aussi efficace que possible sur les ordinateurs multi-core etc.

Ceci est essentiellement fait dans un DataItemUpdater classe qui ressemble à ceci:

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);
    }
}

(Le paramètre objet inutile pour RunCommandsOnContainer est parce que je suis expérimenté avec cela avec et sans l'aide de fils, et l'un d'entre eux nécessite un certain paramètre. En outre, le réglage de la priorité à abovenormal est juste une expérience aussi bien.)

Cela fonctionne bien pour tous, mais un scénario -. Quand j'utilise le type d'objet AllWordsMatcher qui cherche des objets DataItem contenant tous les mots sont recherchés (par opposition à tous les mots, expression exacte, expression régulière, par exemple)

Ceci est un objet basé somestring.Contains(eachWord) assez simple, soutenu par des tests unitaires. Mais c'est là une bizarrerie poilu.

RunCommandsOnContainer exécute à l'aide des fils de ThreadPool, il retournera des résultats fous. Dire que j'ai une chaîne comme ceci:

var someString = "123123123 - just some numbers";

Et je lance ceci:

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

Quand il fonctionne, cela fait revenir vrai beaucoup - j'ai des informations de débogage qui montre le renvoyer vrai pour les chaînes vides et d'autres chaînes qui ne contiennent tout simplement pas les données. En outre, il quelques fois return false, même si la chaîne contient en fait les données recherchées.

Le botteur dans tout cela? Pourquoi est-ce que je soupçonne le ThreadPool et non mon propre code?

Quand je lance le RunCommandsOnContainer () pour chaque conteneur dans mon thread principal (à savoir le verrouillage de l'interface utilisateur et tout), cela fonctionne correctement 100% - à chaque fois! Il ne trouve jamais rien, il ne devrait pas, et il saute jamais rien qu'elle aurait dû trouver.

Cependant, dès que je l'utilise ThreadPool, il commence à trouver un beaucoup d'éléments il ne devrait pas, alors que quelques fois de ne pas trouver les articles il se doit.

Je sais que c'est un problème complexe (il est pénible d'essayer de debug, c'est sûr!), Mais tout de comprendre pourquoi et comment résoudre ce problème serait grandement apprécié!

Merci!

Rune

Était-ce utile?

La solution

Il est un peu difficile de voir du fragment que vous affichez, mais à en juger par les symptômes, je regarde les AllWordsMatcher (cherchez état statique). Si AllWordsMatcher est stateful, vous devriez également vérifier que vous créez une nouvelle instance pour chaque thread.

Plus généralement je regarde toutes les instances impliquées dans le processus correspondant / recherche, en particulier sur les objets de travail utilisés lorsque multithread. De l'expérience passée, le problème est généralement là. (Il est facile de regarder trop le graphique d'objets représentant vos données d'affaires Container / DataItem dans ce cas)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top