private static void enqueueMessage(TraceTypeEnum traceType, string?filterText, ref string?threadMessageBuffer) { #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): start " + traceType.ShortString() + ": " + threadMessageBuffer); #endif TraceMessage message = new TraceMessage(traceType, threadMessageBuffer !, filterText); threadMessageBuffer = null; //break in debugger if needed if (Debugger.IsAttached) { if ((traceType == TraceTypeEnum.Warning && IsBreakOnWarning) || (traceType == TraceTypeEnum.Error && IsBreakOnError) || (traceType == TraceTypeEnum.Exception && IsBreakOnException)) { Debug.WriteLine(traceType + ": " + message); Debugger.Break(); } } #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): lock messagesQueue"); #endif lock (messagesQueue){ #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): locked messagesQueue"); #endif if (messagesQueue.Count >= MaxMessageQueue - 1) //leave 1 space empty for overflow error message { #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): messagesQueue overflow (" + messagesQueue.Count + " messages)"); #endif if (!isMessagesQueueOverflow) { isMessagesQueueOverflow = true; messagesQueue.Enqueue(new TraceMessage(TraceTypeEnum.Error, "Tracer.enqueueMessage(): MessagesQueue overflow (" + messagesQueue.Count + " messages) for:" + Environment.NewLine + message.ToString())); } } else { isMessagesQueueOverflow = false; messagesQueue.Enqueue(message); #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): message added to messagesQueue"); #endif } //Monitor.Pulse(messagesQueue); #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): messagesQueue pulsed, release lock"); #endif } #if RealTimeTraceing RealTimeTracer.Trace("enqueueMessage(): messagesQueue lock released, end"); #endif }
/// <summary> /// Stops tracing. /// </summary> public static void StopTracing() { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: StopTracing()"); #endif lock (tracerTimer) { if (!isDoTracing) { return; } isDoTracing = true; tracerTimer.Dispose(); } }
private static void tracerTimerMethod(object?state) { try { //thread needs to catch its exceptions #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: start"); #endif if (!isDoTracing) { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: tracing has stopped"); #endif return; } if (isTracerTimerMethodRunning) { //if tracerTimerMethod is still running from last scheduled call, there is no point to execute it in parallel //on a different thread. #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: new execution was stopped, because previous call is still active."); #endif return; } try { isTracerTimerMethodRunning = true; TraceMessage[] newTracerMessages; #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer:lock messagesQueue"); #endif lock (messagesQueue) { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer:messagesQueue locked"); #endif if (messagesQueue.Count == 0) { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: queue empty, unlock messagesQueue"); #endif return; } //process new message newTracerMessages = messagesQueue.ToArray(); messagesQueue.Clear(); #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: read " + newTracerMessages.Length + " message(s), unlock messagesQueue"); #endif } #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: messagesQueue unlocked"); #endif //copy message to messageBuffer #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: lock messageBuffer"); #endif lock (messageBuffer) {//need to lock writing so that reading can lock too to get a consistent set of messages #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: messageBuffer locked, copy messages"); #endif foreach (TraceMessage newTracerMessage in newTracerMessages) { if (messageBuffer.Count == MaxMessageBuffer - 1) { messageBuffer.Dequeue(); } messageBuffer.Enqueue(newTracerMessage); } #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: unlock messageBuffer"); #endif } #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: messageBuffer unlocked"); #endif //call event handlers for MessagesTraced if (MessagesTraced != null) { foreach (System.Action <TracerLib.TraceMessage[]> handler in MessagesTraced.GetInvocationList()) { try { handler(newTracerMessages); } catch (Exception ex) { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: Exception in EventHandler !!!: " + ex.Message); #endif ShowExceptionInDebugger(ex); //todo: show exception in the other exception handlers } } #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: all eventhandlers executed"); #endif } } finally { isTracerTimerMethodRunning = false; } } catch (Exception ex) { #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: Exception !!!: " + ex.Message); #endif ShowExceptionInDebugger(ex); // Console.WriteLine("Error in tracerThread." + ex.ToDetailString()); } #if RealTimeTraceing RealTimeTracer.Trace("TracerTimer: completed"); #endif }