Domanda

Ho questi oggetti contenitori (diamo loro contenitore di chiamata) in un elenco. Ognuno di questi oggetti container a sua volta ha un DataItem (o un derivato) in un elenco. In uno scenario tipico un utente avrà 15-20 Gli oggetti contenitore con 1000-5000 DataItems ciascuno. Poi ci sono alcuni oggetti DataMatcher che possono essere utilizzati per diversi tipi di ricerche. Questi lavori in gran parte bene (dal momento che ho diverse centinaia di test di unità su di loro), ma al fine di rendere la mia applicazione WPF sentire scattante e reattivo, ho deciso che avrei dovuto usare il ThreadPool per questo compito. Così ho un DataItemCommandRunner che gira su un oggetto contenitore, e in fondo si esibisce ogni delegato in un elenco che serve come parametro su ogni DataItem a sua volta; Io uso il ThreadPool mettersi in coda un thread per ogni contenitore, in modo che la ricerca in teoria dovrebbe essere il più efficiente possibile su computer multi-core, ecc.

Questo è fondamentalmente fatto in un DataItemUpdater di classe che sembra qualcosa di simile:

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

(Il parametro oggetto inutile per RunCommandsOnContainer è perché sto sperimentando con questo con e senza l'utilizzo di fili, e uno di essi richiede un certo parametro. Inoltre, impostare la priorità a AboveNormal è solo un esperimento pure.)

Questo funziona bene per tutti, ma uno scenario -. Quando uso il tipo di oggetto AllWordsMatcher che cercare oggetti DataItem che contengono tutte le parole da ricercare (al contrario di qualsiasi parola, frase esatta o espressioni regolari per esempio)

Questo è un piuttosto semplice oggetto basato somestring.Contains(eachWord), sostenuta da prove di unità. Ma qui sta una certa stranezza peloso.

Quando il RunCommandsOnContainer corre utilizzando thread ThreadPool, restituisca risultati folli. Dire che ho una stringa come questa:

var someString = "123123123 - just some numbers";

E corro questo:

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

Quando viene eseguito, questo sarà effettivamente tornare vero un bel po '- ho le informazioni di debug che mostra il ritorno vero per le stringhe vuote e altre stringhe che semplicemente non contengono i dati. Inoltre, sarà a volte restituisce false anche quando la stringa contiene in realtà i dati che vengono cercati.

La cosa peggiore in tutto questo? Perché ho il sospetto che il ThreadPool e non il mio codice?

Quando eseguo il RunCommandsOnContainer () di comando per ogni contenitore nel mio thread principale (vale a dire il blocco l'interfaccia utente e tutto), funziona al 100% in modo corretto - ogni volta! E non trova mai niente non dovrebbe, e non è mai salta nulla avrebbe dovuto trovare.

Tuttavia, non appena uso il ThreadPool, comincia a trovare un sacco di elementi non dovrebbe, mentre alcune volte non trovando oggetti dovrebbe.

Mi rendo conto che questo è un problema complesso (è doloroso cercando di eseguire il debug, questo è certo!), Ma qualsiasi informazioni sul perché e come risolvere questo problema sarebbe molto apprezzato!

Grazie!

Rune

È stato utile?

Soluzione

E 'un po' difficile da vedere dal frammento si sta inviando, ma a giudicare dai sintomi vorrei guardare l'AllWordsMatcher (cercate condizione statica). Se AllWordsMatcher è stateful si dovrebbe anche controllare che si sta creando una nuova istanza per ciascun thread.

Più in generale mi piacerebbe guardare in tutte le istanze coinvolte nel corrispondente / processo di ricerca, in particolare presso gli oggetti attivi vengono utilizzati quando multithread. Dalle esperienze passate, il problema di solito si trova lì. (E 'facile guardare troppo il grafico oggetto che rappresenta il vostro contenitore dati aziendali / DataItem in questo caso)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top