Pergunta

Eu tenho algo wich olha para mim como condição de corrida, enquanto o registo para o arquivo de rosca múltipla.

1) Eu tenho uma classe logger personalizada (ConfigurableTraceLogger) que é compartilhada por vários segmentos no meu aplicativo. É tem muitas funções wrapper que todas as chamadas para a função núcleo principal

protected void TraceData(String category, TraceEventType type, EventId id, string prefix, string format)
{
    foreach (TraceListener item in _listeners)
    {
        IConfigurableTraceListener cl = item as IConfigurableTraceListener;

        if (cl != null && cl.Category == category.ToLower())
        {

            if (DisplayMethodName)
                item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
            else
                item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, format);

            item.Flush();
        }
    }
}

Como você pode ver minha classe simplesmente armazena classe TraceListner-derved diferente em uma coleção _listeners. Basicamente, existem apenas console e de arquivo de texto ouvintes. O que TraceData faz que leva o nome da categoria (ou seja, registro de start-up) e encontra o ouvinte direita. Todos os ouvintes são definidos pelo nome do arquivo de configuração

Agora eu também tenho meus ouvintes personalizados na coleção

public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener

Essa classe personalizada substituições nada, exceto para uma propriedade.

protected override string[] GetSupportedAttributes()
{
    return new string[] { "category" };
}

Quando eu começar o meu pedido depois de 5 a 10 minutos eu recebo exceção na chamada

           item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);

Exceção está dizendo:

"condição Provável corrida I / O detectados durante a cópia de memória. O pacote de E / S não é thread-safe por padrão. Em vários segmentos aplicativos, um fluxo deve ser acessado de uma forma thread-safe, como um fio envoltório -safe retornado por TextReader de ou métodos sincronizados de TextWriter. Isso também se aplica a classes como StreamWriter e StreamReader. "

Depois que eu continuo recebendo segundo muitas exceção de vezes na mesma chamada para

item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);

Exceção

Conde não pode ser inferior a zero. Nome do parâmetro: contagem rastreamento de pilha: "no System.String.CopyTo (Int32 sourceIndex, Char [] destino, Int32 destinationIndex, contagem Int32) \ r \ n no System.IO.StreamWriter.Write (String value) \ r \ n no System.Diagnostics. TextWriterTraceListener.Write (string mensagem) \ r \ n na System.Diagnostics.TraceListener.WriteHeader (fonte string, TraceEventType eventType, Int32 ID) \ r \ n na System.Diagnostics.TraceListener.TraceData (TraceEventCache EventCache, fonte string, TraceEventType eventType , Int32 ID, dados Object) \ r \ n na Jfc.Configuration.ConfigurableTraceLogger.TraceData (categoria string, tipo TraceEventType, EventId ID, string prefixo, formato string, Object [] args) "

Parece-me que a minha classe não é thread-safe bem a chamada para TraceData. Mas ConfigurableTextWriterTraceListener é dito para o segmento de seguros depois de tudo. No entanto eu verifiquei IsThreadSafe propety para minha classe derivada TextWriterTraceListener em tempo de execução e falsa. Eu estou tentando descobrir onde está o problema.

Foi útil?

Solução

Isso significa que diz - o seu TraceListener não é thread-safe e pausas quando acessado a partir de vários threads. Você precisa fazer seus ouvintes o segmento de seguros ou encontrar uma maneira de garantir que apenas um thread acessa qualquer instância particular.

Uma maneira de torná-los thread-safe é usar uma fila sincronizada e fazer todas as suas chamadas enfileirar itens de dados para a fila enquanto os Retiradas da fila TraceListener 'reais'-los e escreve-los para fora em um segmento separado.

Você também tem que ter cuidado com o seu dicionário de ouvintes - a atualização do dicionário não é thread-safe, mas se você nunca acessá-lo antes da última atualização é aplicada, você pode deixá-lo como é

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