Pergunta

Eu tenho esses objetos de recipiente (chamá-los Container do LET) em uma lista. Cada um desses objetos Container, por sua vez tem um DataItem (ou um derivado) em uma lista. Em um cenário típico de um usuário terá 15-20 objetos recipiente com 1000-5000 DataItems cada. Depois, há alguns objetos DataMatcher que podem ser usados ??para diferentes tipos de pesquisas. Estes trabalham principalmente excelentes (desde que eu tenho várias centenas de testes de unidade sobre eles), mas para fazer minha aplicação WPF sensação ágil e responsivo, eu decidi que eu deveria usar o ThreadPool para esta tarefa. Assim eu tenho um DataItemCommandRunner que é executado em um objeto Container, e basicamente executa cada delegado em uma lista que leva como parâmetro em cada DataItem por sua vez; Eu uso o ThreadPool fazer fila um thread para cada recipiente, de modo que a pesquisa em teoria deveria ser tão eficiente quanto possível em computadores multi-core etc.

Este é basicamente feito em um DataItemUpdater classe que é algo como isto:

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

(O parâmetro objeto inútil para RunCommandsOnContainer é porque eu estou experimentando com isso com e sem o uso de fios, e um deles requer algum parâmetro. Além disso, definir a prioridade para AboveNormal é apenas um experimento bem.)

Esta multa funciona para todos, mas um cenário - quando eu uso o tipo de objeto AllWordsMatcher que vai olhar para DataItem objetos contendo todas as palavras sendo procurado (em oposição a qualquer palavra, frase exata ou expressão regular, por exemplo)

Este é um bastante simples objeto com base somestring.Contains(eachWord), apoiada por testes de unidade. Mas aqui reside alguma estranheza cabeludo.

Quando o RunCommandsOnContainer ensaios, com tópicos ThreadPool, ela retorne resultados insanos. Digamos que eu tenha uma seqüência como esta:

var someString = "123123123 - just some numbers";

E eu executar este:

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

Quando ele é executado, isto irá realmente retornar verdadeiro bastante - Tenho informações que mostram que retornar verdadeiro para cadeias vazias e outras cordas que simplesmente não contêm os dados de depuração. Além disso, ele vai algumas vezes retornar false mesmo quando a cadeia contém realmente os dados sendo procurado.

O retrocesso em tudo isso? Por que eu suspeito que o ThreadPool e não meu próprio código?

Quando eu executar o RunCommandsOnContainer () comando para cada contêiner no meu thread principal (ou seja, bloqueando a interface do usuário e tudo), ele funciona 100% corretamente - cada vez! Ele nunca encontra nada que não deveria, e nunca ignora qualquer coisa que deveria ter encontrado.

No entanto, assim que eu uso o ThreadPool, ele começa a encontrar um monte de itens não deve, enquanto algumas vezes não encontrar itens que deveria.

Sei que este é um problema complexo (é doloroso tentando depurar, isso é certo!), Mas qualquer visão sobre por que e como corrigir isso seria muito apreciada!

Obrigado!

Rune

Foi útil?

Solução

É um pouco difícil de ver a partir do fragmento que você está postando, mas a julgar pelos sintomas que eu iria olhar para o AllWordsMatcher (olhar para o estado estático). Se AllWordsMatcher é stateful você também deve verificar que você está criando uma nova instância para cada thread.

De modo mais geral eu olhar para todas as instâncias envolvidas na correspondência / processo de pesquisa, especificamente para os objetos de trabalho a ser usado quando vários segmentos. A experiência do passado, o problema geralmente está lá. (É fácil olhar muito no gráfico de objeto que representa seus dados de negócios Container / DataItem neste caso)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top