Performance Messung unter C#

Hallo Leute! Da ich mich momentan damit beschäftige, ein paar Funktionen einer Leistungsprüfung zu unterziehen, habe ich nach einer Möglichkeit gesucht, recht bequem die Leistung der Funktionen zu messen. Auf dem Weg bin ich auf ein paar Methoden gestoßen, welche von der WinAPI bereit gestellt werden. Da aber vielleicht noch die Möglichkeit bestehen soll, dies mit .Net-Bordmitteln zu bewerkstelligen, habe ich die primitivste Möglichkeit der Messung hinzugefügt. Und zwar über DateTime. Hier meine Kleine aber feine Lösung. Ich habe die Klasse erstmal Performance genannt, da ich diese Klasse vielleicht noch erweitere.
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Klasse zu Performance-Messung im Code
/// </summary>
public class Performance
{
/// <summary>
///
/// </summary>
/// <param name="QueryPerformanceCounter"></param>
/// <returns></returns>
[DllImport("KERNEL32")]
public static extern bool QueryPerformanceCounter(ref long QueryPerformanceCounter);
/// <summary>
///
/// </summary>
/// <param name="QueryPerformanceFrequency"></param>
/// <returns></returns>
[DllImport("KERNEL32")]
public static extern bool QueryPerformanceFrequency(ref long QueryPerformanceFrequency);
/// <summary>
/// Frequenz des PerformanceCounter
/// </summary>
private long Frequency;
/// <summary>
/// Startzeit der Messung
/// </summary>
private long StartTime;
/// <summary>
/// Endzeit der Messung
/// </summary>
private long EndTime;
/// <summary>
/// Flag zur Festlegung, ob die WindowsAPI benutzt werden soll
/// </summary>
private bool UseWinAPI;
/// <summary>
/// Konstruktor
/// </summary>
public Performance()
{
this.Initialize(true);
}
/// <summary>
/// Konstruktor
/// </summary>
/// <param name="UseWinAPI"></param>
public Performance(bool UseWinAPI)
{
this.Initialize(UseWinAPI);
}
/// <summary>
/// Initialisierung
/// </summary>
/// <returns></returns>
protected void Initialize(bool UseWinAPI)
{
this.UseWinAPI = UseWinAPI;
this.StartTime = this.EndTime = 0;
if (UseWinAPI) QueryPerformanceFrequency(ref this.Frequency);
else this.Frequency = 10000000;
}
/// <summary>
/// Messung starten
/// </summary>
public void Start()
{
if (this.UseWinAPI) QueryPerformanceCounter(ref this.StartTime);
else this.StartTime = DateTime.Now.Ticks;
}
/// <summary>
/// Messung beenden
/// </summary>
/// <returns></returns>
public double Stop()
{
if (this.UseWinAPI) QueryPerformanceCounter(ref this.EndTime);
else this.EndTime = DateTime.Now.Ticks;
return ((this.EndTime - this.StartTime) / (double)this.Frequency);
}
}
KeyHook

Ich habe mir mal die Mühe gemacht, eine Klasse zu basteln, welche auf Tastatureingaben reagiert. Dabei werde alle Eingaben eingefangen, welche durch die Tastatur erfolgen. Das Fenster der Anwendung muss also nicht aktiv sein.
Über den angelegten EventHandler kann man diese Eingaben dann einfach mit per Event abfangen.
Die Grundstruktur, auf die dieser Snippet basiert findet ihr hier
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace KeyEvent
{
class InterceptKeys
{
///
///
///
public InterceptKeys()
{
this._proc = HookCallback;
SetHook(_proc);
}
///
///
///
~InterceptKeys()
{
UnhookWindowsHookEx(_hookID);
}
///
///
///
public const int WH_KEYBOARD_LL = 13;
///
///
///
public const int WM_KEYDOWN = 0x0100;
///
///
///
public LowLevelKeyboardProc _proc;
///
///
///
public static IntPtr _hookID = IntPtr.Zero;
///
///
///
/// <param name="proc" /> ///
public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
///
///
///
/// <param name="nCode" /> /// <param name="wParam" /> /// <param name="lParam" /> ///
public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
///
///
///
/// <param name="nCode" /> /// <param name="wParam" /> /// <param name="lParam" /> ///
public IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
OnInput(new KeyEventArgs((Keys)vkCode));
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
///
///
///
/// <param name="idHook" /> /// <param name="lpfn" /> /// <param name="hMod" /> /// <param name="dwThreadId" /> ///
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
///
///
///
/// <param name="hhk" /> ///
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
///
///
///
/// <param name="hhk" /> /// <param name="nCode" /> /// <param name="wParam" /> /// <param name="lParam" /> ///
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
///
///
///
/// <param name="lpModuleName" /> ///
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
///
///
///
/// <param name="sender" /> /// <param name="e" /> public delegate void KeyEventHandler(object sender, KeyEventArgs e);
///
///
///
public event KeyEventHandler Input;
///
/// Invoke the Changed event; called whenever list changes
///
/// <param name="e" /> protected void OnInput(KeyEventArgs e)
{
if (this.Input == null) return;
System.ComponentModel.AsyncOperationManager.CreateOperation(null).Post(new System.Threading.SendOrPostCallback(delegate(object obj) { try { this.Input(this, e); } catch { } }), null);
}
}
}