Domanda

Ho qualcosa che sembra a me come condizione di competizione durante la registrazione di file da più thread.

1) ho un logger personalizzato di classe (ConfigurableTraceLogger) che è condiviso da più thread nella mia applicazione.Si ha un sacco di funzioni wrapper che tutti chiamata al nucleo principale funzione

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

Come potete vedere la mia classe memorizza i diversi TraceListner-derved di classe, in una collezione _listeners.Fondamentalmente ci sono solo console e file di testo ascoltatori.Cosa TraceData prende il nome della categoria (es.la registrazione di start-up) e trova il suo ascoltatore.A tutti gli ascoltatori sono definite dal nome del file di config

Ora ho anche la mia custom ascoltatori della collezione

public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener

Che classe personalizzata sostituzioni nulla tranne che per una proprietà.

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

Quando avvio la mia applicazione dopo 5 a 10 minuti ricevo eccezione la chiamata

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

Eccezione dicendo:

"Probabile di I/O condizione di competizione rilevato durante la copia di memoria.L'I/O pacchetto non è thread-safe per impostazione predefinita.Nelle applicazioni multithreading, un flusso deve essere letta in un thread-safe, come un thread-safe wrapper restituito dal TextReader o TextWriter Sincronizzato metodi.Questo vale anche per le classi come StreamWriter e StreamReader."

Dopo di che ho sempre seconda eccezione un sacco di volte nella stessa chiamata al

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

Eccezione

Conte non potrà essere inferiore a zero.Nome del parametro:conte Stack trace:"al Sistema.Stringa.CopyTo(Int32 sourceIndex, Char[] destinazione, Int32 destinationIndex, Int32 conte) al Sistema.IO.StreamWriter.Write(String value) al Sistema.Diagnostica.TextWriterTraceListener.Write(String messaggio) al Sistema.Diagnostica.TraceListener.WriteHeader(String source, TraceEventType eventType, Int32 id) al Sistema.Diagnostica.TraceListener.TraceData(TraceEventCache eventCache, la Stringa di origine, TraceEventType eventType, Int32 id, dati Oggetto) a Jfc.Di configurazione.ConfigurableTraceLogger.TraceData(Stringa di categoria, TraceEventType tipo di Evento id, String prefix, formato String, Object[] args)"

Mi sembra che la mia classe non è thread-safe e la chiamata a TraceData.Ma ConfigurableTextWriterTraceListener si dice thread-safe, dopo tutto.Comunque ho controllato IsThreadSafe propety per il mio TextWriterTraceListener classe derivata a run-time ed è falso.Sto cercando di capire dove è il problema.

È stato utile?

Soluzione

Significa quello che dice il tuo TraceListener non è thread-safe e si rompe quando si accede da più thread.È necessario per rendere i vostri ascoltatori thread-safe o trovare un modo per garantire che un solo thread accede ad una particolare istanza.

Un modo per rendere la loro thread-safe è quello di utilizzare un sincronizzati coda e fare tutte le chiamate enqueue elementi di dati per la coda, mentre il 'reale' traceListener annulla loro e li scrive in un thread separato.

È inoltre necessario essere attenti con il vostro dizionario di ascoltatori - aggiornamento del dizionario non è thread-safe, ma se mai di accesso prima che l'ultimo aggiornamento applicato, si può lasciare così com'è

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