Cansado de usar la clase StopWatch y repetir siempre la misma lógica , decidí crearme un cronometro para tomar el tiempo de cualquier método. El post lo voy a hacer breve, así que explico rápidamente algunas características y al final esta el ejemplo para descargar:
- Clase Cronometro con 3 métodos estáticos TomarTiempo, la respuesta a la toma del tiempo es una instancia de la clase CronometroResultado que contiene un TimeSpan (fraccion de tiempo) , resultado del método invocado y un flag que indica si el metodo fue encontrado.
- Soporte para metodos con y sin parámetros.
- TomarTiempo se encarga de buscar el metodo por nombre y coincidencia de cantidad y tipo de parametros.
- Busquedas usando Reflection.
- Aun no tiene soporte para métodos genéricos.
- No importa el orden en que se envian los parametros, TomarTiempo se encarga de buscar el coincidente.
La verdad que me resulta mucho mas comodo ahora medir los ticks, milisegundos , segundos ,etc con esta forma , acá va la clase completa y como dije al final el fuente ..... lo demas para que lo investiguen ...
Clase Cronometro ....
public class Cronometro
{
///
/// Usar esta carga para invocar metodos de instancia
///
/// Tipo de la clase que contiene el metodo. Ejemplo: typeof(MiClase)
/// Nombre del metodo, no es case sensitive
/// Array de object con los parametros que se le pasaran al metodo encontrado
/// CronometroResultado
public static CronometroResultado TomarTiempo(object instance, string nombreMetodo, object[] arguments)
{
return TomarTiempo(instance.GetType(), instance, nombreMetodo, arguments);
}
///
/// Usar esta carga para invocar metodos estaticos
///
/// Tipo de la clase que contiene el metodo. Ejemplo: typeof(MiClase)
/// Nombre del metodo, no es case sensitive
/// Array de object con los parametros que se le pasaran al metodo encontrado
/// CronometroResultado
public static CronometroResultado TomarTiempo(Type type, string nombreMetodo, object[] arguments)
{
return TomarTiempo(type, null, nombreMetodo, arguments);
}
internal static CronometroResultado TomarTiempo(Type tipo, object instance, string nombreMetodo, object[] arguments)
{
MethodInfo ejecutar = null;
bool searchStatics = instance == null;
nombreMetodo = nombreMetodo.ToLower();
//buscar dentro de los metodos encontrados si alguno coincide con los parametros enviados
MethodInfo[] metodos =
tipo.GetMethods().Where(m => m.Name.ToLower() == nombreMetodo & m.IsStatic == searchStatics).ToArray();
//Soporte para metodos que no tienen parametros de entrada
if (arguments == null || arguments.Length == 0)
{
ejecutar = metodos.Where(m => m.GetParameters().Length == 0).FirstOrDefault();
}
else
{
//entre todos los metodos busco los parametros que coincidan
foreach (var met in metodos)
{
ParameterInfo[] pars = met.GetParameters();
//coincide busco el orden de los parametos
if (pars.Length == arguments.Length )
{
Int16 coincidencias = 0;
for (int i = 0; i < pars.Length; i++)
{
if (pars[i].ParameterType.Name == arguments[i].GetType().Name)
{
++coincidencias;
}
}
if (coincidencias == pars.Length)
{
ejecutar = met;
goto continuar;
}
}
}
}
continuar:
CronometroResultado resultado = new CronometroResultado();
Stopwatch reloj = new Stopwatch();
if (ejecutar != null && !ejecutar.IsGenericMethod) //sin soporte para genericos
{
reloj.Start();
resultado.Resultado = ejecutar.Invoke(instance, arguments);
reloj.Stop();
resultado.MetodoEncontrado = true;
}
resultado.Tiempo = reloj.Elapsed;
return resultado;
}
}
Clase CronometroResultado ....
public class CronometroResultado
{
private TimeSpan _span;
public bool MetodoEncontrado { get; set; }
public TimeSpan Tiempo
{
get { return _span; }
set
{
_span = value;
}
}
public object Resultado { get; set; }
}
Una pruebita al metodo Vender de la clase Venta ...
Venta v = new Venta();
var res = Cronometro.TomarTiempo(v, "vender", new object[] { 1, 2 });
Console.WriteLine("Resultado ejecución");
Console.WriteLine("--------------------");
Console.WriteLine(res.MetodoEncontrado ? "Encontrado" : "No encontrado");
Console.WriteLine("Ticks: " + res.Tiempo.Ticks.ToString());
Console.WriteLine("Milisegundos: " + res.Tiempo.Milliseconds.ToString());
Console.WriteLine("Segundos: " + res.Tiempo.Seconds.ToString());
Console.WriteLine("Resultado: " + res.Resultado);
Console.WriteLine("");
Console.WriteLine("");
Espero que sirva ... aca el ejemplo Descargar
Excelente entrada, voy a ponerlo en práctica
ResponderEliminar