¿Cómo puedo agregar un Trace () a cada llamada a un método en C#?


Estoy teniendo dificultades para rastrear un problema de bloqueo, por lo que me gustaría registrar la entrada y salida de cada llamada de método. He hecho esto antes con C++ sin tener que agregar código a cada método. Es esto posible con C#?

Author: Jon Tackabury, 2009-02-18

8 answers

Probablemente tu mejor opción sería usar un framework AOP (aspect oriented programming) para llamar automáticamente al código de seguimiento antes y después de la ejecución de un método. Una opción popular para AOP y. NET es PostSharp .

 19
Author: Dennis G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-07 23:32:50

Un generador de perfiles es ideal para ver su código en ejecución durante el desarrollo, pero si está buscando la capacidad de hacer trazas personalizadas en producción, entonces, como mencionó Denis G., PostSharp es la herramienta perfecta: no tiene que cambiar todo su código y puede activarlo/desactivarlo fácilmente.

También es fácil de configurar en pocos minutos y Gaël Fraiteur, el creador de PostSharp, incluso tiene videos que muestran lo fácil que es agregar seguimiento a una aplicación existente.
Usted encontrará ejemplos y tutoriales en la sección de documentación .

 3
Author: Renaud Bompuis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-21 23:44:10

Si su objetivo principal es registrar los puntos de entrada/salida de la función y la información ocasional en el medio, he tenido buenos resultados con un objeto de registro Desechable donde el el constructor rastrea la entrada de la función, y Dispose () rastrea la salida. Esto permite que calling code simplemente envuelva el código de cada método dentro de una única instrucción usando. También se proporcionan métodos para registros arbitrarios en el medio. Aquí hay una clase completa de rastreo de eventos C # ETW junto con una función wrapper de entrada / salida:

using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace MyExample
{
    // This class traces function entry/exit
    // Constructor is used to automatically log function entry.
    // Dispose is used to automatically log function exit.
    // use "using(FnTraceWrap x = new FnTraceWrap()){ function code }" pattern for function entry/exit tracing
    public class FnTraceWrap : IDisposable
    {
        string methodName;
        string className;

        private bool _disposed = false;

        public FnTraceWrap()
        {
            StackFrame frame;
            MethodBase method;

            frame = new StackFrame(1);
            method = frame.GetMethod();
            this.methodName = method.Name;
            this.className = method.DeclaringType.Name;

            MyEventSourceClass.Log.TraceEnter(this.className, this.methodName);
        }

        public void TraceMessage(string format, params object[] args)
        {
            string message = String.Format(format, args);
            MyEventSourceClass.Log.TraceMessage(message);
        }

        public void Dispose()
        {
            if (!this._disposed)
            {
                this._disposed = true;
                MyEventSourceClass.Log.TraceExit(this.className, this.methodName);
            }
        }
    }

    [EventSource(Name = "MyEventSource")]
    sealed class MyEventSourceClass : EventSource
    {
        // Global singleton instance
        public static MyEventSourceClass Log = new MyEventSourceClass();

        private MyEventSourceClass()
        {
        }

        [Event(1, Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
        public void TraceMessage(string message)
        {
            WriteEvent(1, message);
        }

        [Event(2, Message = "{0}({1}) - {2}: {3}", Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
        public void TraceCodeLine([CallerFilePath] string filePath = "",
                                  [CallerLineNumber] int line = 0,
                                  [CallerMemberName] string memberName = "", string message = "")
        {
            WriteEvent(2, filePath, line, memberName, message);
        }

        // Function-level entry and exit tracing
        [Event(3, Message = "Entering {0}.{1}", Opcode = EventOpcode.Start, Level = EventLevel.Informational)]
        public void TraceEnter(string className, string methodName)
        {
            WriteEvent(3, className, methodName);
        }

        [Event(4, Message = "Exiting {0}.{1}", Opcode = EventOpcode.Stop, Level = EventLevel.Informational)]
        public void TraceExit(string className, string methodName)
        {
            WriteEvent(4, className, methodName);
        }
    }
}

El código que lo usa se verá algo como esto:

public void DoWork(string foo)
{
    using (FnTraceWrap fnTrace = new FnTraceWrap())
    {
        fnTrace.TraceMessage("Doing work on {0}.", foo);
        /*
        code ...
        */
    }
}
 3
Author: Eric C. Berridge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-31 23:20:07

Use Perfilador de HORMIGAS de Red Gate sería su mejor apuesta. En su defecto, busque en interceptores en Castillo Windsor . Sin embargo, eso supone que estás cargando tus tipos a través de IoC.

La reflexión es otra forma, puede usar el Sistema .Reflexión.Emit métodos para "escribir" código en memoria. Ese código podría reemplazar el código de su método y ejecutarlo, pero con el registro apropiado. Buena suerte en eso, sin embargo... Más fácil sería utilizar un Aspecto Marco de programación orientado como Aspect#.

 2
Author: Neil Barnwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-24 14:06:29

Podría estar esperando que el problema de bloqueo se mantenga, haciendo un volcado de memoria y analizando la pila de llamadas en varios subprocesos. Puede usar DebugDiago el script adplus (modo hang, en este caso) que viene con Herramientas de depuración para Windows.

Tess Ferrandez también tiene una excelente serie de laboratorio sobre aprender a depurar varios problemas usando volcados de memoria.NET. Lo recomiendo encarecidamente.

 1
Author: Richard Szalay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-24 14:19:25

¿Cómo sabes que está pasando? Si esta es una aplicación multiproceso, recomendaría probar la condición y llamar al Sistema.Diagnostico.Depurador.Break () en tiempo de ejecución cuando se detecta. Luego, simplemente abre la ventana de Subprocesos y recorre las pilas de llamadas en cada subproceso relevante.

 0
Author: Robert Venables,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-18 01:27:47
 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-08 21:00:05

Pruebe jetbrains dottrace es un Generador de perfiles de rendimiento.NET. no tienes que modificar tu código. y te da 10 días para el juicio.

Aquí hay un tutorial para dottrace

 -1
Author: Taha Amin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-17 13:40:15