Pro ladění a řešení problémů v běžící aplikaci může mnohdy pomoci tracing mechanizmus tj. logování informaci z aktuálně prováděného kódu (real-time). .NET platforma obsahuje pro tracing podporu. Ta je umístěna v namespace System.Diagnostics, kde jsou kromě třídy Trace k dispozici i další třídy jako TraceListener, TraceSwitch, TraceFilter. K tomu abychom odhalili případný problém v naší aplikaci nám ale mnohdy postačí velmi jednoduchá implementace trace mechanizmu, kterou si zde ukážeme.
V místech, kde chceme vypisovat zprávy pro ladění budeme v naší aplikaci pouze volat následující příkaz:
Trace.WriteLine("Tracing");
Volání metody WriteLine směruje text do tzv. Trace Listeneru. Ten určuje, kam se budou trasovací informace předávat. Těchto listenerů je v .NET implementováno několik a většinou se konfigurují .config souborem aplikace. Pokud nic nebudeme nastavovat, tak je jako výchozí listener automaticky zapnut DefaultTraceListener, který zprávy posílá pomoci Win32 API funkce OutputDebugString přímo do Windows kernelu.
Všechny metody ve třídě Trace jsou pomoci atributu podmíněné na TRACE direktivu. Tím se také třída Trace liší od třídy Debug, která má metody podmíněné direktivou DEBUG. Ve vlastnostech Build projektu pak můžeme určit, zda jsou TRACE a DEBUG konstanty zapnuté. Výchozí nastavení je takové, že TRACE konstanta je zapnutá i v Release konfiguraci (na rozdíl od DEBUG).
V .NET aplikaci jsou tedy při použití Trace ve výchozím nastavení zprávy přes OutputDebugString posílány do systému. K tomu, abychom tyto zprávy získali, použijeme Sysinternals utilitu DebugView (Dbgview.exe). K dispozici ke stažení je zde.
V aplikaci stačí mít zapnuto Capture Win32 a Capture Events (defaultně je zapnuto) a zprávy jsou zobrazovány. Dále aplikace nabízí funkce Filter/Highlight. Toto nám pro zjištění co se v běžící aplikaci děje mnohdy postačí. DebugView dále dokonce nabízí funkci pro připojení ke vzdálenému počítači.
Používání trace v aplikaci můžeme malinko vylepšit následující pomocnou metodou:
//Set trace level from configuration
private static readonly TraceLevel s_TraceLevel = (TraceLevel)TraceLogger.Properties.Settings.Default.TraceLevel;
internal static void WriteTrace(TraceLevel traceLevel, string message)
{
if (traceLevel <= s_TraceLevel)
{
string str = string.Format(CultureInfo.InvariantCulture, "[{0,-7}@{1:HH}:{1:mm}:{1:ss}.{1:fff}] {2}", traceLevel.ToString(), DateTime.UtcNow, message);
Trace.WriteLine(str);
}
}
Metoda WriteTrace nám navíc vypisuje i čas vzniku zprávy a dále umožnuje výpis filtrovat podle přidaného nastavení TraceLevel (zde implementováno pomoci settings souboru). To může být někdy vhodné, abychom mohli detailnější výpis zapnout až v případě, kdy ladíme konkrétní problém, a v jiných situacích tak nebyla aplikace zatížena posíláním zpráv.
Je zde ale pár situací, kdy nejsou zprávy v DebugView zobrazované, jsou to:
- Pokud je k .NET 4.0 aplikaci připojen debugger – např. Visual Studio, pak jsou trace výstupy přesměrovány to jeho Output okna a do DebugView již posílány nejsou. Pro výstup do DebugView je nutné z Visual Studia aplikaci spustit bez ladění (Ctrl-F5). Je to dle Microsoftu by design, ve starší verzi Frameworku 3.5 byly zprávy posílány jak do Output okna tak to DebugView.
- Pokud se jedná o Windows Service (sem patří i w3wp.exe proces webových aplikací), které běží pod jiným účtem, v jiné session, musíme pro zobrazení zpráv DebugView spustit pod právy administrator a poté zapnout volbu Capture Global Win32 (více je popsáno zde).
Pozn.: Na starších systémech (Windows Server 2003, Windows XP) tato volba není dostupná. Při spuštění DebugView je možné zobrazit zprávy pokud je Windows service spuštěn pod Local System účtem, ale pokud je spuštěn pod NETWORK SERVICE, tak zprávy zobrazovány nejsou.