문제

여러 스레드에서 파일로 기록하는 동안 인종 조건처럼 보이는 것이 있습니다.

1) 응용 프로그램의 여러 스레드에서 공유하는 사용자 정의 로거 클래스 (ConfigurableTraceLogger)가 있습니다. 모든 주 핵심 기능을 호출하는 많은 래퍼 함수가 있습니다.

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

보시다시피 내 수업은 단순히 컬렉션 _listeners에 다른 tracelistner-ended 클래스를 저장합니다. 기본적으로 콘솔 및 텍스트 파일 리스너 만 있습니다. Tracedata는 카테고리 이름 (예 : 로깅 시작)을 취하고 올바른 리스너를 찾습니다. 모든 리스너는 구성 파일 이름으로 정의됩니다

이제 컬렉션에 커스텀 리스너도 있습니다.

public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener

해당 커스텀 클래스는 한 속성을 제외하고는 아무것도 무시하지 않습니다.

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

5 ~ 10 분 후 신청서를 시작하면 전화에서 예외가 발생합니다.

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

예외는 다음과 같습니다.

"메모리를 복사하는 동안 감지 가능한 I/O 경주 조건. I/O 패키지는 기본적으로 스레드 안전하지 않습니다. 멀티 스레드 애플리케이션에서는 TexTreader의 스레드 안전 래퍼와 같은 스레드 안전 방식으로 스트림에 액세스해야합니다. 또는 TextWriter의 동기화 된 메소드. 이것은 StreamWriter 및 StreamReader와 같은 클래스에도 적용됩니다. "

그 후 나는 같은 전화에서 두 번째 예외를 계속 얻습니다.

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

예외

카운트는 0보다 작을 수 없습니다. 매개 변수 이름 : 카운트 스택 추적 : "at System.String.copyto (int32 sourceIndex, char [] 대상, int32 destinationIndex, int32 count) r n at System.io.StreamWriter.write (String value) r n at System.Diagnostics.TextWriterTraceListener.write (문자열 메시지) r n at System.diagnostics.traceListener.writeHeader (String 소스, TraceEventType EventType, Int32 ID) n System.diagnostics.diagnostics.traceListEner.Tracache, stratCache, stratecache, stratecache at r n 소스, TraceEventType eventType, int32 ID, 객체 데이터) r n at jfc.configuration.configurabletraceLogger.traceAta (문자열 카테고리, traceEventType 유형, eventID ID, String Prefix, String Format, Object [] args) "

내 수업은 스레드 안전하지 않으며 Tracedata에 대한 호출이있는 것 같습니다. 그러나 configurableTextWriterTracelistener는 결국 안전 스레드라고합니다. 그러나 런타임에 내 TextWriterTracelistener 파생 클래스에 대한 IsthreadSafe 제안을 확인했습니다. 문제가 어디에 있는지 알아 내려고 노력하고 있습니다.

도움이 되었습니까?

해결책

그것은 말한 것을 의미합니다 - 당신의 tracelistener는 스레드 안전하지 않으며 여러 스레드에서 액세스 할 때 파손됩니다. 청취자 스레드를 안전하게 만들거나 하나의 스레드 만 특정 인스턴스에 액세스 할 수있는 방법을 찾아야합니다.

스레드 안전을 안전하게 만드는 한 가지 방법은 동기화 된 큐를 사용하고 모든 통화를 큐에 큐에 넣는 반면 '실제'Tracelistener는이를 퇴적하여 별도의 스레드로 작성하는 것입니다.

또한 청취자 사전에주의를 기울여야합니다. 사전 업데이트는 스레드 안전하지 않지만 마지막 업데이트가 적용되기 전에 액세스 할 수없는 경우 그대로 남겨 둘 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top