Loggning och spårning i .NET-program
När du fortsätter att utveckla ditt program och det blir mer komplext vill du använda ytterligare felsökningsdiagnostik för ditt program.
Spårning är ett sätt för dig att övervaka din applikations körning medan den körs. Du kan lägga till spårnings- och felsökningsinstrumentation i .NET-programmet när du utvecklar det. Du kan använda den instrumentationen när du utvecklar programmet och när du har distribuerat det.
Den här enkla tekniken är förvånansvärt kraftfull. Du kan använda den i situationer där du behöver mer än ett felsökningsprogram:
- Problem som uppstår under långa tidsperioder kan vara svåra att felsöka med ett traditionellt felsökningsprogram. Loggar möjliggör detaljerad granskning efter döden som sträcker sig över långa tidsperioder. Felsökningsprogram är däremot begränsade till realtidsanalys.
- Program med flera trådar och distribuerade program är ofta svåra att felsöka. Att ansluta ett felsökningsprogram tenderar att ändra beteenden. Du kan analysera detaljerade loggar efter behov för att förstå komplexa system.
- Problem i distribuerade program kan uppstå på grund av en komplex interaktion mellan många komponenter. Det kanske inte är rimligt att ansluta ett felsökningsprogram till alla delar av systemet.
- Många tjänster bör inte stoppas. När ett felsökningsprogram ansluts kan det ofta leda till tidsgränsfel.
- Problem förutses inte alltid. Loggning och spårning är utformade för låg belastning så att program alltid kan registreras om ett problem uppstår.
Skriva information till utdatafönster
Fram tills nu har vi använt konsolen för att visa information för programanvändaren. Det finns andra typer av program som skapats med .NET som har användargränssnitt, till exempel mobil-, webb- och skrivbordsappar, och det finns ingen synlig konsol. I dessa program loggar System.Console meddelanden "bakom kulisserna". Dessa meddelanden kan visas i ett utdatafönster i Visual Studio eller Visual Studio Code. De kan också loggas i en systemlogg, till exempel Androids logcat. Därför bör du ta stor hänsyn till när du använder System.Console.WriteLine i ett program som inte är konsolprogram.
Det är här du kan använda System.Diagnostics.Debug och System.Diagnostics.Trace utöver System.Console. Både Debug och Trace ingår i System.Diagnostics och skrivs bara till loggar när en lämplig lyssnare är ansluten.
Det är upp till dig att välja vilket API för utskriftsformat som ska användas. De viktigaste skillnaderna är:
-
System.Console
- Alltid aktiverad och skriver alltid till konsolen.
- Användbar för information som din kund kan behöva se i utgåvan.
- Eftersom det är den enklaste metoden används den ofta för tillfällig ad hoc-felsökning. Den här felsökningskoden checkas ofta aldrig in på källkontrollen.
-
System.Diagnostics.Trace
- Aktiveras endast när
TRACEhar definierats. - Skriver till anslutna lyssnare, som standard DefaultTraceListener.
- Använd det här API:et när du skapar loggar som ska aktiveras i de flesta versioner.
- Aktiveras endast när
-
System.Diagnostics.Debug
- Aktiveras endast när
DEBUGhar definierats (när du är i felsökningsläge). - Skriver till ett anslutet felsökningsprogram.
- Använd det här API:et när du skapar loggar som endast ska aktiveras i felsökningsversioner.
- Aktiveras endast när
Console.WriteLine("This message is readable by the end user.");
Trace.WriteLine("This is a trace message when tracing the app.");
Debug.WriteLine("This is a debug message just for developers.");
När du utformar din spårnings- och felsökningsstrategi bör du tänka på hur du vill att utdata ska se ut. Flera skrivinstruktioner fyllda med orelaterad information skapar en logg som är svår att läsa. Att använda WriteLine för att placera relaterade instruktioner på separata rader kan däremot göra det svårt att skilja på vilken information som hör ihop. I allmänhet använder du flera Write-satser när du vill kombinera information från flera källor för att skapa ett informativt meddelande. Använd WriteLine-instruktionen när du vill skapa ett enda fullständigt meddelande.
Debug.Write("Debug - ");
Debug.WriteLine("This is a full line.");
Debug.WriteLine("This is another full line.");
Dessa utdata kommer från föregående loggning med Debug:
Debug - This is a full line.
This is another full line.
Definiera TRACE- och DEBUG-konstanter
När ett program körs under felsökning definieras som standard den DEBUG konstanten. Du kan styra detta genom att lägga till en DefineConstants post i projektfilen i en egenskapsgrupp. Här är ett exempel på hur du aktiverar TRACE för både Debug- och Release-konfigurationer utöver DEBUG för Debug konfigurationer.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
När du använder Trace utan att vara ansluten till debuggern måste du konfigurera en spårningslyssnare som dotnet-trace.
Villkorsstyrd spårning
Förutom enkla Write- och WriteLine-metoder finns det även möjlighet att lägga till villkor med WriteIf och WriteLineIf. Till exempel kontrollerar följande logik om antalet är noll och skriver sedan ett felsökningsmeddelande:
if(count == 0)
{
Debug.WriteLine("The count is 0 and this may cause an exception.");
}
Du kan skriva om detta på en enda kodrad:
Debug.WriteLineIf(count == 0, "The count is 0 and this may cause an exception.");
Du kan också använda dessa villkor med Trace och med flaggor som du definierar i ditt program:
bool errorFlag = false;
System.Diagnostics.Trace.WriteIf(errorFlag, "Error in AppendData procedure.");
System.Diagnostics.Debug.WriteIf(errorFlag, "Transaction abandoned.");
System.Diagnostics.Trace.Write("Invalid value for data request");
Kontrollera att vissa villkor finns
Ett påstående, eller en Assert-instruktion, testar ett villkor som du anger som ett argument för Assert-instruktionen. Om villkoret utvärderas till trueinträffar ingen åtgärd. Om villkoret utvärderas till falsemisslyckas försäkran. Om du kör med en felsökningsversion går programmet in i pausläge.
Du kan använda metoden Assert från antingen Debug eller Trace, som finns i namnområdet System.Diagnostics.
Debug klassens metoder ingår inte i en släppversion av programmet, så de varken ökar storleken eller minskar hastigheten på släppkoden.
Använd metoden System.Diagnostics.Debug.Assert fritt för att testa villkor som ska gälla om koden är korrekt. Anta till exempel att du har skrivit en heltalsdelningsfunktion. Enligt matematikens regler kan divisorn aldrig vara noll. Du kan testa det här villkoret med hjälp av en försäkran:
int IntegerDivide(int dividend, int divisor)
{
Debug.Assert(divisor != 0, $"{nameof(divisor)} is 0 and will cause an exception.");
return dividend / divisor;
}
När du kör den här koden under felsökningsprogrammet utvärderas försäkran. Jämförelsen görs dock inte i utgåveversionen, så det finns ingen extra belastning.
Not
När du använder System.Diagnostics.Debug.Assertkontrollerar du att all kod i Assert inte ändrar programmets resultat om Assert tas bort. Annars kan du oavsiktligt introducera en bugg som bara visas i utgåvan av ditt program. Var särskilt försiktig med assertioner som innehåller funktions- eller proceduranrop.
Att använda Debug och Trace från System.Diagnostics-namnområdet är ett bra sätt att ge ytterligare kontext när du kör och felsöker ditt program.