Megosztás a következőn keresztül:


Kivételek és hibák kezelése

A kivételek a szolgáltatáson vagy az ügyfél implementálásán belüli hibák helyi közlésére szolgálnak. A hibák viszont a szolgáltatáshatárok közötti hibák közlésére szolgálnak, például a kiszolgálóról az ügyfélre, vagy fordítva. A közlekedési csatornák a hibák mellett gyakran használnak szállításspecifikus mechanizmusokat a szállítási szintű hibák közlésére. A HTTP-átvitel például a 404-hez hasonló állapotkódokat használ egy nem létező végpont URL-címének kommunikációjához (nincs végpont a hiba visszaküldéséhez). Ez a dokumentum három szakaszból áll, amelyek útmutatást nyújtanak az egyéni csatornaszerzők számára. Az első szakasz útmutatást nyújt arra vonatkozóan, hogy mikor és hogyan definiálhat és dobhat ki kivételeket. A második szakasz útmutatást nyújt a hibák generálásával és felhasználásával kapcsolatban. A harmadik szakasz bemutatja, hogyan adhat meg nyomkövetési információkat az egyéni csatorna felhasználójának a futó alkalmazások hibaelhárításához.

Kivételek

A kivétel dobásakor két dolgot kell szem előtt tartani: Először is olyan típusúnak kell lennie, amely lehetővé teszi a felhasználók számára, hogy helyes kódot írjanak, amelyek megfelelően reagálhatnak a kivételre. Másodszor, elegendő információt kell megadnia ahhoz, hogy a felhasználó megértse, mi a hiba, a hiba hatása, és hogyan lehet kijavítani. Az alábbi szakaszok útmutatást nyújtanak a Windows Communication Foundation (WCF) csatornák kivételtípusaihoz és üzeneteihez. A .NET-kivételekre vonatkozó általános útmutatást a Kivételek tervezési útmutatója dokumentumban is találhat.

Kivételtípusok

A csatornák által kidobott kivételeknek vagy egy System.TimeoutException, System.ServiceModel.CommunicationExceptionvagy a forrásból CommunicationExceptionszármaztatott típusnak kell lenniük. (Az olyan kivételek is előfordulhatnak, mint például ObjectDisposedException , de csak azt jelzik, hogy a hívó kód visszaélt a csatornával. Ha egy csatornát helyesen használ, csak a megadott kivételeket kell megadnia.) A WCF hét kivételtípust biztosít, amelyek a csatornákból származnak CommunicationException , és amelyeket csatornák általi használatra terveztek. Vannak más CommunicationExceptionszármaztatott kivételek is, amelyeket a rendszer más részei használnak. Ezek a kivételtípusok a következők:

Kivétel típusa Értelmezés Belső kivétel tartalma Helyreállítási stratégia
AddressAlreadyInUseException A figyeléshez megadott végpontcím már használatban van. Ha jelen van, a kivételt okozó átviteli hibával kapcsolatos további részleteket tartalmaz. Például. PipeException, vagy HttpListenerExceptionSocketException. Próbálkozzon egy másik címmel.
AddressAccessDeniedException A folyamat nem fér hozzá a figyeléshez megadott végpontcímhez. Ha jelen van, a kivételt okozó átviteli hibával kapcsolatos további részleteket tartalmaz. Például, PipeExceptionvagy HttpListenerException. Próbálkozzon különböző hitelesítő adatokkal.
CommunicationObjectFaultedException A ICommunicationObject használt állapot hibás (további információ: Állapotváltozások ismertetése). Vegye figyelembe, hogy ha egy több függőben lévő hívással rendelkező objektum hibás állapotba vált, csak egy hívás a hibával kapcsolatos kivételt eredményez, a többi hívás pedig egy CommunicationObjectFaultedException. Ez a kivétel általában azért fordul elő, mert egy alkalmazás figyelmen kívül hagy egy kivételt, és megpróbál egy már hibás objektumot használni, esetleg egy olyan szálon, amely nem az eredeti kivételt kapta. Ha jelen van, részletes információkat tartalmaz a belső kivételről. Hozzon létre egy új objektumot. Vegye figyelembe, hogy attól függően, hogy mi okozta a ICommunicationObject hibát, előfordulhat, hogy más munka is szükséges a helyreállításhoz.
CommunicationObjectAbortedException A ICommunicationObject használat megszakadt (további információ: Állapotváltozások ismertetése). A kivételhez CommunicationObjectFaultedExceptionhasonlóan ez a kivétel azt jelzi, hogy az alkalmazás meghívta Abort az objektumot, esetleg egy másik szálról, és az objektum már nem használható emiatt. Ha jelen van, részletes információkat tartalmaz a belső kivételről. Hozzon létre egy új objektumot. Vegye figyelembe, hogy attól függően, hogy mi okozta a ICommunicationObject megszakítást az első helyen, előfordulhat, hogy más munka szükséges a helyreállításhoz.
EndpointNotFoundException A cél távoli végpont nem figyel. Ennek az lehet az eredménye, hogy a végpontcím bármely része helytelen, megoldhatatlan vagy a végpont leállt. Ilyen például a DNS-hiba, a Queue Manager nem érhető el, és a szolgáltatás nem fut. A belső kivétel általában a mögöttes átvitelből nyújt részleteket. Próbálkozzon egy másik címmel. Másik lehetőségként előfordulhat, hogy a feladó vár egy ideig, és próbálkozzon újra, ha a szolgáltatás leállt
ProtocolException A végpont házirendje szerint a kommunikációs protokollok nem egyeznek a végpontok között. Például a tartalomtípus nem egyezik, vagy túllépte az üzenet maximális méretét. Ha jelen van, további információt nyújt az adott protokollhibáról. Ez például a belső kivétel, QuotaExceededException ha a hiba oka meghaladja a MaxReceivedMessageSize értéket. Helyreállítás: Győződjön meg arról, hogy a feladó és a fogadott protokoll beállításai egyeznek. Ennek egyik módja, ha újra importálja a szolgáltatásvégpont metaadatait (szabályzatát), és a létrehozott kötés használatával hozza létre újra a csatornát.
ServerTooBusyException A távoli végpont figyel, de nem áll készen az üzenetek feldolgozására. Ha jelen van, a belső kivétel megadja a SOAP-hiba vagy az átviteli szintű hiba részleteit. Helyreállítás: Várjon, és próbálkozzon újra a műveletet később.
TimeoutException A művelet nem fejeződött be az időtúllépési időszakon belül. Az időtúllépés részleteit is megadhatja. Várjon, és próbálkozzon újra a műveletet később.

Csak akkor adjon meg új kivételtípust, ha ez a típus az összes meglévő kivételtípustól eltérő helyreállítási stratégiának felel meg. Ha új kivételtípust határoz meg, annak származnia kell, vagy annak egyik származtatott osztályából kell származnia CommunicationException .

Kivételüzenetek

A kivételüzenetek nem a programra, hanem a felhasználóra irányulnak, ezért elegendő információt kell nyújtaniuk ahhoz, hogy segítsenek a felhasználónak megérteni és megoldani a problémát. A jó kivételről szóló üzenet három alapvető része a következő:

Mi történt. Adja meg a probléma egyértelmű leírását a felhasználói élményhez kapcsolódó kifejezések használatával. A hibás kivétel üzenete például "Érvénytelen konfigurációs szakasz". Így a felhasználó azon gondolkodik, hogy melyik konfigurációs szakasz helytelen, és miért helytelen. Továbbfejlesztett üzenet: "Érvénytelen konfigurációs szakasz <customBinding>". Még jobb üzenet lenne a következő: "Nem lehet hozzáadni a myTransport nevű átvitelt a myBinding nevű kötéshez, mert a kötés már rendelkezik egy myTransport nevű átvitelsel". Ez egy nagyon konkrét üzenet olyan kifejezések és nevek használatával, amelyeket a felhasználó könnyen azonosíthat az alkalmazás konfigurációs fájljában. Azonban még mindig hiányzik néhány kulcsfontosságú összetevő.

A hiba jelentősége. Hacsak az üzenet nem közli egyértelműen, hogy mit jelent a hiba, a felhasználó valószínűleg azon gondolkodik, hogy végzetes hiba-e, vagy figyelmen kívül hagyható. Az üzeneteknek általában a hiba jelentésével vagy jelentésével kell vezetniük. Az előző példa továbbfejlesztéséhez a következő üzenet jelenhet meg: "A ServiceHost konfigurációs hiba miatt nem nyitható meg: Nem lehet hozzáadni a myTransport nevű átvitelt a myBinding nevű kötéshez, mert a kötés már rendelkezik myTransport nevű átvitelsel".

Hogyan kell a felhasználónak kijavítani a problémát. Az üzenet legfontosabb része, hogy segítse a felhasználót a probléma megoldásában. Az üzenetnek útmutatást vagy tippeket kell tartalmaznia arról, hogy mit kell ellenőrizni vagy kijavítani a probléma megoldásához. Például: "A ServiceHost konfigurációs hiba miatt nem nyitható meg: Nem lehet hozzáadni a myTransport nevű átvitelt a myBinding nevű kötéshez, mert a kötés már rendelkezik myTransport nevű átvitelsel. Győződjön meg arról, hogy a kötésben csak egy átvitel szerepel."

Hibák közlése

A SOAP 1.1 és a SOAP 1.2 is meghatározott struktúrát határoz meg a hibákhoz. A két specifikáció között van néhány különbség, de általában az Üzenet és a MessageFault típus szolgál a hibák létrehozására és felhasználására.

SOAP 1.2 Fault and SOAP 1.1 Fault
SOAP 1.2 Hiba (balra) és SOAP 1.1 hiba (jobbra). A SOAP 1.1-ben csak a hibaelem rendelkezik névtér-minősítéssel.

A SOAP a hibaüzenetet olyan üzenetként definiálja, amely csak egy hibaelemet (egy olyan elemet) tartalmaz, amelynek a neve <env:Fault>) a hiba gyermekeként <env:Body>. A hibaelem tartalma kissé eltér a SOAP 1.1 és a SOAP 1.2 között az 1. ábrán látható módon. Az System.ServiceModel.Channels.MessageFault osztály azonban egy objektummodellre normalizálja ezeket a különbségeket:

public abstract class MessageFault  
{  
    protected MessageFault();  
  
    public virtual string Actor { get; }  
    public virtual string Node { get; }  
    public static string DefaultAction { get; }  
    public abstract FaultCode Code { get; }  
    public abstract bool HasDetail { get; }  
    public abstract FaultReason Reason { get; }  
  
    public T GetDetail<T>();  
    public T GetDetail<T>( XmlObjectSerializer serializer);  
    public System.Xml.XmlDictionaryReader GetReaderAtDetailContents();  
  
    // other methods omitted  
}  

A Code tulajdonság megfelel a (vagy faultCode a env:Code SOAP 1.1)-nek, és azonosítja a hiba típusát. A SOAP 1.2 öt megengedhető értéket faultCode határoz meg (például Feladó és Fogadó), és meghatároz egy Subcode elemet, amely bármilyen alkódértéket tartalmazhat. (Lásd: SOAP 1.2 specifikáció az engedélyezett hibakódok listájához és jelentésükhöz.) A SOAP 1.1 egy kissé eltérő mechanizmussal rendelkezik: Négy faultCode értéket határoz meg (például ügyfél és kiszolgáló), amelyek kibővíthetők teljesen újak definiálásával, vagy a pont jelölésével pontosabb faultCodes, például Client.Authentication.

Ha a MessageFault használatával programozza a hibákat, a FaultCode.Name és a FaultCode.Namespace leképezi a SOAP 1.2 env:Code vagy a SOAP 1.1 faultCodenevét és névterét. A FaultCode.SubCode a SOAP 1.2-hez env:Subcode képez le, és a SOAP 1.1 esetében null értékű.

Új hiba alkódokat (vagy új hibakódokat kell létrehoznia a SOAP 1.1 használata esetén), ha érdekes programozott módon megkülönböztetni egy hibát. Ez hasonló egy új kivételtípus létrehozásához. A SOAP 1.1 hibakódokkal ne használja a pont jelölést. (A A WS-I alapprofil a hibakód pont jelölésének használatát is elriasztja.)

public class FaultCode  
{  
    public FaultCode(string name);  
    public FaultCode(string name, FaultCode subCode);  
    public FaultCode(string name, string ns);  
    public FaultCode(string name, string ns, FaultCode subCode);  
  
    public bool IsPredefinedFault { get; }  
    public bool IsReceiverFault { get; }  
    public bool IsSenderFault { get; }  
    public string Name { get; }  
    public string Namespace { get; }  
    public FaultCode SubCode { get; }  
  
//  methods omitted  
  
}  

A Reason tulajdonság egy env:Reason kivétel üzenetéhez hasonló, ember által olvasható leírásnak felel meg (vagy faultString a SOAP 1.1-ben). Az FaultReason osztály (és a SOAP env:Reason/faultString) beépített támogatást nyújt a globalizáció érdekében több fordításhoz.

public class FaultReason  
{  
    public FaultReason(FaultReasonText translation);  
    public FaultReason(IEnumerable<FaultReasonText> translations);  
    public FaultReason(string text);  
  
    public SynchronizedReadOnlyCollection<FaultReasonText> Translations
    {
       get;
    }  
  
 }  

A hiba részleteinek tartalma a MessageFaulton különböző módszerekkel jelenik meg, beleértve a T> és GetReaderAtDetailContentsa GetDetail<() metódust is. A hiba részletei egy átlátszatlan elem, amely további részleteket tartalmaz a hibáról. Ez akkor hasznos, ha valamilyen tetszőleges strukturált részletet szeretne a hibával együtt hordozni.

Hibák generálása

Ez a szakasz a csatornában vagy a csatorna által létrehozott üzenettulajdonságokban észlelt hibaállapotra adott hiba esetén keletkező hibát mutatja be. Tipikus példa az érvénytelen adatokat tartalmazó kérésüzenetre adott hiba visszaküldése.

Hiba létrehozásakor az egyéni csatornának nem szabad közvetlenül elküldenie a hibát, hanem kivételt kell küldenie, és hagyja, hogy a fenti réteg döntse el, hogy a kivételt hibaként konvertálja-e, és hogyan küldje el. Az átalakítás támogatásához a csatornának olyan implementációt FaultConverter kell biztosítania, amely képes az egyéni csatorna által okozott kivételt a megfelelő hibára konvertálni. FaultConverter a következőként van definiálva:

public class FaultConverter  
{  
    public static FaultConverter GetDefaultFaultConverter(  
                                   MessageVersion version);  
    protected abstract bool OnTryCreateFaultMessage(  
                                   Exception exception,
                                   out Message message);  
    public bool TryCreateFaultMessage(  
                                   Exception exception,
                                   out Message message);  
}  

Minden egyéni hibát generáló csatornának implementálnia FaultConverter kell és vissza kell adnia azt egy hívásból.GetProperty<FaultConverter> Az egyéni OnTryCreateFaultMessage implementációnak vagy hibássá kell alakítania a kivételt, vagy delegálnia kell a belső csatorna FaultConverter. Ha a csatorna átvitel, akkor a kivételt vagy a delegálást a kódoló FaultConverter vagy a WCF-ben megadott alapértelmezett FaultConverter értékre kell konvertálnia. Az alapértelmezett FaultConverter átalakítja a WS-Addressing és a SOAP által megadott hibaüzeneteknek megfelelő hibákat. Íme egy példa OnTryCreateFaultMessage implementáció.

public override bool OnTryCreateFaultMessage(Exception exception,
                                             out Message message)  
{  
    if (exception is ...)  
    {  
        message = ...;  
        return true;  
    }  
  
#if IMPLEMENTING_TRANSPORT_CHANNEL  
    FaultConverter encoderConverter =
                    this.encoder.GetProperty<FaultConverter>();  
    if ((encoderConverter != null) &&
        (encoderConverter.TryCreateFaultMessage(  
         exception, out message)))  
    {  
        return true;  
    }  
  
    FaultConverter defaultConverter =
                   FaultConverter.GetDefaultFaultConverter(  
                   this.channel.messageVersion);  
    return defaultConverter.TryCreateFaultMessage(  
                   exception,
                   out message);  
#else  
    FaultConverter inner =
                   this.innerChannel.GetProperty<FaultConverter>();  
    if (inner != null)  
    {  
        return inner.TryCreateFaultMessage(exception, out message);  
    }  
    else  
    {  
        message = null;  
        return false;  
    }  
#endif  
}  

Ennek a mintának az a következménye, hogy a hibákat igénylő hibafeltételek rétegei közötti kivételeknek elegendő információt kell tartalmazniuk ahhoz, hogy a megfelelő hibagenerátor létrehozza a megfelelő hibát. Egyéni csatornaszerzőként különböző hibafeltételeknek megfelelő kivételtípusokat határozhat meg, ha ezek a kivételek még nem léteznek. Vegye figyelembe, hogy a csatornarétegeket átlátszatlan hibaadatok helyett a hibaállapotnak kell jeleznie.

Hibakategóriák

A hibáknak általában három kategóriája van:

  1. Az egész veremen átható hibák. Ezek a hibák a csatorna verem bármely rétegében előfordulhatnak, például InvalidCardinalityAddressingException.

  2. A verem egy adott rétege felett bárhol előforduló hibák, például egy tranzakcióval vagy biztonsági szerepkörrel kapcsolatos hibák.

  3. A verem egy rétegére irányított hibák, például olyan hibák, mint a WS-RM sorozatszám hibái.

1. kategória. A hibák általában ws-addressing és SOAP hibák. A WCF által biztosított alaposztály FaultConverter átalakítja a WS-Addressing és a SOAP által megadott hibaüzeneteknek megfelelő hibákat, így önnek nem kell kezelnie a kivételek konvertálását.

2. kategória. Hibák akkor fordulnak elő, ha egy réteg olyan tulajdonságot ad hozzá az üzenethez, amely nem használja fel teljesen az adott rétegre vonatkozó üzenetadatokat. Később hibák jelentkezhetnek, amikor egy magasabb réteg kéri az üzenet tulajdonságát az üzenetadatok további feldolgozására. Az ilyen csatornáknak a GetProperty korábban megadott módon kell megvalósítaniuk, hogy a magasabb réteg a megfelelő hibát küldje vissza. Erre példa a TransactionMessageProperty. Ez a tulajdonság a fejléc összes adatának teljes ellenőrzése nélkül kerül az üzenetbe (ennek során kapcsolatba kell lépnie az elosztott tranzakció koordinátorával (DTC).

3. kategória. A hibákat csak a processzor egyetlen rétege hozza létre és küldi el. Ezért az összes kivétel a rétegen belül található. A csatornák konzisztenciájának javítása és a karbantartás megkönnyítése érdekében az egyéni csatornának a korábban megadott mintát kell használnia, hogy még belső hibák esetén is hibaüzeneteket hozzon létre.

Fogadott hibák értelmezése

Ez a szakasz útmutatást nyújt a hibaüzenetek fogadása során a megfelelő kivétel létrehozásához. Az üzenet feldolgozására szolgáló döntési fa a verem minden rétegében a következő:

  1. Ha a réteg érvénytelennek tekinti az üzenetet, a rétegnek az "érvénytelen üzenet" feldolgozását kell elvégeznie. Az ilyen feldolgozás a rétegre vonatkozik, de magában foglalhatja az üzenet elvetése, a nyomkövetés vagy egy kivétel elvetése, amely hibává alakul. Ilyenek például a nem megfelelő védelemmel ellátott üzenetek fogadása, illetve a hibás sorszámú üzenet fogadása az RM-ben.

  2. Ellenkező esetben, ha az üzenet egy olyan hibaüzenet, amely kifejezetten a rétegre vonatkozik, és az üzenet nem értelmezhető a réteg interakcióján kívül, a rétegnek kezelnie kell a hibafeltételt. Erre példa az RM-sorozat visszautasított hibája, amely az RM-csatorna feletti rétegek számára értelmetlen, és amely az RM-csatorna hibáját és a függőben lévő műveletekből való dobást jelenti.

  3. Ellenkező esetben az üzenetet a Request() vagy a Receive() üzenetből kell visszaadni. Ide tartoznak azok az esetek, amikor a réteg felismeri a hibát, de a hiba csak azt jelzi, hogy egy kérés meghiúsult, és nem jelenti a csatorna hibáját és a függőben lévő műveletekből való dobást. Ilyen esetben a használhatóság javítása érdekében a rétegnek olyan FaultConverter származtatott osztályt kell implementálnia GetProperty<FaultConverter> és visszaadnia, amely felülírással OnTryCreateExceptionképes a hibát kivételsé alakítani.

Az alábbi objektummodell támogatja az üzenetek kivételekké alakítását:

public class FaultConverter  
{  
    public static FaultConverter GetDefaultFaultConverter(  
                                  MessageVersion version);  
    protected abstract bool OnTryCreateException(  
                                 Message message,
                                 MessageFault fault,
                                 out Exception exception);  
    public bool TryCreateException(  
                                 Message message,
                                 MessageFault fault,
                                 out Exception exception);  
}  

A csatornarétegek implementálhatók GetProperty<FaultConverter> a hibaüzenetek kivételekké alakításának támogatásához. Ehhez felülbírálhatja OnTryCreateException és megvizsgálhatja a hibaüzenetet. Ha felismerte, végezze el az átalakítást, ellenkező esetben kérje meg a belső csatornát, hogy konvertálja azt. Az átviteli csatornáknak delegálniuk FaultConverter.GetDefaultFaultConverter kell az alapértelmezett SOAP/WS-Addressing FaultConverter beszerzéséhez.

Egy tipikus implementáció a következőképpen néz ki:

public override bool OnTryCreateException(  
                            Message message,
                            MessageFault fault,
                            out Exception exception)  
{  
    if (message.Action == "...")  
    {  
        exception = ...;  
        return true;  
    }  
    // OR  
    if ((fault.Code.Name == "...") && (fault.Code.Namespace == "..."))  
    {  
        exception = ...;  
        return true;  
    }  
  
    if (fault.IsMustUnderstand)  
    {  
        if (fault.WasHeaderNotUnderstood(  
                   message.Headers, "...", "..."))  
        {  
            exception = new ProtocolException(...);  
            return true;  
        }  
    }  
  
#if IMPLEMENTING_TRANSPORT_CHANNEL  
    FaultConverter encoderConverter =
              this.encoder.GetProperty<FaultConverter>();  
    if ((encoderConverter != null) &&
        (encoderConverter.TryCreateException(  
                              message, fault, out exception)))  
    {  
        return true;  
    }  
  
    FaultConverter defaultConverter =  
             FaultConverter.GetDefaultFaultConverter(  
                             this.channel.messageVersion);  
    return defaultConverter.TryCreateException(  
                             message, fault, out exception);  
#else  
    FaultConverter inner =
                    this.innerChannel.GetProperty<FaultConverter>();  
    if (inner != null)  
    {  
        return inner.TryCreateException(message, fault, out exception);  
    }  
    else  
    {  
        exception = null;  
        return false;  
    }  
#endif  
}  

A különböző helyreállítási forgatókönyvekkel rendelkező konkrét hibaállapotok esetében fontolja meg a származtatott osztály definiálását ProtocolException.

MustUnderstand feldolgozás

A SOAP általános hibát határoz meg annak jelzésére, hogy a fogadó nem értette meg a szükséges fejlécet. Ezt a hibát a hibának mustUnderstand nevezzük. A WCF-ben az egyéni csatornák soha nem hoznak létre mustUnderstand hibákat. Ehelyett a WCF kommunikációs verem tetején található WCF-diszpécser ellenőrzi, hogy a mustUnderstand=true jelölésű fejléceket a mögöttes verem értelmezte-e. Ha bármelyiket nem értjük, mustUnderstand akkor a rendszer ekkor hibát hoz létre. (A felhasználó kikapcsolhatja ezt a mustUnderstand feldolgozást, és beállíthatja, hogy az alkalmazás megkapja az összes üzenetfejlécet. Ebben az esetben az alkalmazás felelős a feldolgozásért mustUnderstand .) A létrehozott hiba tartalmaz egy NotUnderstood fejlécet, amely tartalmazza az összes olyan fejléc nevét, amelynek MustUnderstand=true értéke nem volt értelmezhető.

Ha a protokollcsatorna egy egyéni fejlécet küld MustUnderstand=true értékre, és hibát kap mustUnderstand , ki kell derítenie, hogy a hiba az elküldött fejléc miatt van-e. Az osztálynak két tagja MessageFault van, amelyek hasznosak ehhez:

public class MessageFault  
{  
    ...  
    public bool IsMustUnderstandFault { get; }  
    public static bool WasHeaderNotUnderstood(MessageHeaders headers,
        string name, string ns) { }  
    ...  
  
}  

IsMustUnderstandFault akkor ad true vissza, ha a hiba mustUnderstand hiba. WasHeaderNotUnderstood akkor ad true vissza, ha a megadott névtérrel és névtérrel rendelkező fejléc NotUnderstood fejlécként szerepel a hibában. Ellenkező esetben a visszaadott falseérték.

Ha egy csatorna egy MustUnderstand = true jelölésű fejlécet bocsát ki, akkor ennek a rétegnek is implementálnia kell a Exception Generation API-mintát, és a fejléc által okozott hibákat hasznosabb kivételsé kell konvertálnia mustUnderstand a korábban leírtak szerint.

Nyomkövetés

A .NET-keretrendszer egy mechanizmust biztosít a program végrehajtásának nyomon követésére, amely segít az éles alkalmazások diagnosztizálásában vagy az időszakos problémák megoldásában, ahol nem lehet csak egy hibakeresőt csatolni, és végiglépkedni a kódon. A mechanizmus alapvető összetevői a System.Diagnostics névtérben találhatók, és a következőkből állnak:

  • System.Diagnostics.TraceSource, amely az írandó nyomkövetési információk forrása, System.Diagnostics.TraceListeneramely egy absztrakt alaposztály a konkrét figyelők számára, amelyek megkapják a nyomon követendő információkat, TraceSource és egy figyelőspecifikus célhelyre bocsátják ki. Például XmlWriterTraceListener egy XML-fájlban adja ki a nyomkövetési adatokat. Végül, amely lehetővé teszi, System.Diagnostics.TraceSwitchhogy az alkalmazás felhasználója vezérelje a nyomkövetés részletességét, és általában a konfigurációban van megadva.

  • Az alapvető összetevők mellett a Service Trace Viewer tool (SvcTraceViewer.exe) használatával is megtekintheti és kereshet WCF-nyomkövetéseket. Az eszköz kifejezetten a WCF által létrehozott és a használatával kiírt XmlWriterTraceListenernyomkövetési fájlokhoz készült. Az alábbi ábra a nyomkövetésben részt vevő különböző összetevőket mutatja be.

Tracing components

Nyomkövetés egyéni csatornáról

Az egyéni csatornáknak nyomkövetési üzeneteket kell írniuk, hogy segítsenek diagnosztizálni a problémákat, ha nem lehet hibakeresőt csatolni a futó alkalmazáshoz. Ez két magas szintű feladatból áll: példányosítás TraceSource és metódusok meghívása nyomkövetések írásához.

A példányosításkor TraceSourcea megadott sztring lesz a forrás neve. Ez a név a nyomkövetési forrás konfigurálásához (engedélyezés/letiltás/nyomkövetési szint beállítása) használható. A nyomkövetési kimenetben is megjelenik. Az egyéni csatornáknak egyedi forrásnévvel kell segíteniük a nyomkövetési kimenet olvasóinak, hogy megtudják, honnan származnak a nyomkövetési információk. Az általános gyakorlat, hogy az információt a nyomkövetési forrás neveként író szerelvény nevét használja. A WCF például a System.ServiceModel szerelvényből írt információk nyomkövetési forrásaként a System.ServiceModel szerelvényt használja.

Miután rendelkezik nyomkövetési forrással, meghívja annak , TraceEventvagy TraceInformation metódusaitTraceData, hogy nyomkövetési bejegyzéseket írjon a nyomkövetési figyelőknek. Minden megírt nyomkövetési bejegyzéshez az eseménytípust a megadott TraceEventTypeeseménytípusok egyikeként kell besorolnia. Ez a besorolás és a konfiguráció nyomkövetési szintjének beállítása határozza meg, hogy a nyomkövetési bejegyzés kimenete-e a figyelőnek. A nyomkövetési szint konfigurációban Warning való beállításával például lehetővé teszi Warninga nyomkövetési bejegyzések írását, ErrorCritical de letiltja az információ- és részletes bejegyzéseket. Íme egy példa egy nyomkövetési forrás példányosítására és egy bejegyzés információs szintű írására:

using System.Diagnostics;  
//...  
TraceSource udpSource = new TraceSource("Microsoft.Samples.Udp");  
//...  
udpsource.TraceInformation("UdpInputChannel received a message");  

Fontos

Erősen ajánlott olyan nyomkövetési forrásnevet megadnia, amely egyedi az egyéni csatornán, hogy segítsen a nyomkövetési kimenet olvasóinak megérteni, hogy honnan származik a kimenet.

Integráció a Nyomkövetési megjelenítővel

A csatorna által létrehozott nyomkövetések a Service Trace Viewer eszköz (SvcTraceViewer.exe) által olvasható formátumban, nyomkövetési figyelőként használhatókSystem.Diagnostics.XmlWriterTraceListener. Ezt önnek, mint a csatorna fejlesztőjének nem kell megtennie. Ehelyett az alkalmazás felhasználójának (vagy az alkalmazást hibaelhárító személynek) kell konfigurálnia ezt a nyomkövetési figyelőt az alkalmazás konfigurációs fájljában. A következő konfiguráció például a nyomkövetési adatokat a következő fájlból és Microsoft.Samples.Udp a System.ServiceModel nevesített TraceEventsFile.e2efájlból adja ki:

<configuration>  
  <system.diagnostics>  
    <sources>  
      <!-- configure System.ServiceModel trace source -->  
      <source name="System.ServiceModel" switchValue="Verbose"
              propagateActivity="true">  
        <listeners>  
          <add name="e2e" />  
        </listeners>  
      </source>  
      <!-- configure Microsoft.Samples.Udp trace source -->  
      <source name="Microsoft.Samples.Udp" switchValue="Verbose" >  
        <listeners>  
          <add name="e2e" />  
        </listeners>  
      </source>  
    </sources>  
    <!--   
    Define a shared trace listener that outputs to TraceFile.e2e  
    The listener name is e2e   
    -->  
    <sharedListeners>  
      <add name="e2e" type="System.Diagnostics.XmlWriterTraceListener"  
        initializeData=".\TraceFile.e2e"/>  
    </sharedListeners>  
    <trace autoflush="true" />  
  </system.diagnostics>  
</configuration>  

Strukturált adatok nyomon követése

System.Diagnostics.TraceSource olyan metódussal TraceData rendelkezik, amely egy vagy több, a nyomkövetési bejegyzésben szerepeltetni kívánt objektumot vesz igénybe. A metódust általában minden Object.ToString objektumon meghívja a rendszer, az eredményül kapott sztring pedig a nyomkövetési bejegyzés részeként lesz megírva. A nyomkövetések kimenetének használatakor System.Diagnostics.XmlWriterTraceListener adatobjektumként TraceDatatovábbíthat egy System.Xml.XPath.IXPathNavigable elemet. Az eredményként kapott nyomkövetési bejegyzés tartalmazza a System.Xml.XPath.XPathNavigator. Íme egy példabejegyzés XML-alkalmazásadatokkal:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">  
  <System xmlns="...">  
    <EventID>12</EventID>  
    <Type>3</Type>  
    <SubType Name="Information">0</SubType>  
    <Level>8</Level>  
    <TimeCreated SystemTime="2006-01-13T22:58:03.0654832Z" />  
    <Source Name="Microsoft.ServiceModel.Samples.Udp" />  
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />  
    <Execution  ProcessName="UdpTestConsole"
                ProcessID="3348" ThreadID="4" />  
    <Channel />  
    <Computer>COMPUTER-LT01</Computer>  
  </System>  
<!-- XML application data -->  
  <ApplicationData>  
  <TraceData>  
   <DataItem>  
   <TraceRecord
     Severity="Information"  
     xmlns="…">  
        <TraceIdentifier>some trace id</TraceIdentifier>  
        <Description>EndReceive called</Description>  
        <AppDomain>UdpTestConsole.exe</AppDomain>  
        <Source>UdpInputChannel</Source>  
      </TraceRecord>  
    </DataItem>  
  </TraceData>  
  </ApplicationData>  
</E2ETraceEvent>  

A WCF nyomkövetési megjelenítője megérti a TraceRecord korábban bemutatott elem sémáját, kinyeri az adatokat a gyermekelemeiből, és táblázatos formátumban jeleníti meg. A csatornának ezt a sémát kell használnia a strukturált alkalmazásadatok nyomon követésekor, hogy Svctraceviewer.exe a felhasználók olvassák az adatokat.