condição de corrida / TextWriterTraceListener
-
19-09-2019 - |
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.
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 é