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


Az erőforrások biztonságos bezárása és megszakítása hálózati kapcsolatok megszakadása esetén

A UsingUsing minta bemutatja, hogy az Close erőforrásokat a gépelt ügyfél használatakor milyen módszerekkel és Abort módszerekkel lehet megtisztítani. Az using utasítás kivételeket okoz, ha a hálózati kapcsolat nem erős. Ez a minta a számológép szolgáltatást megvalósító első lépéseken alapul. Ebben a mintában az ügyfél egy konzolalkalmazás (.exe), és a szolgáltatást az Internet Information Services (IIS) üzemelteti.

Feljegyzés

A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.

Ez a minta két gyakori problémát mutat be, amelyek a C# "using" utasítás gépelt ügyfelekkel való használatakor fordulnak elő, valamint a kivételek után helyesen megtisztított kódot.

A C# "using" utasítás a () hívását Disposeeredményezi. Ez ugyanaz, mint Close(), amely kivételeket okozhat hálózati hiba esetén. Mivel a () hívása Disposeimplicit módon történik a "használat" blokk záró zárójelében, a kivételek forrása valószínűleg észrevétlen marad mind a kód megírása, mind a kód olvasása során. Ez az alkalmazáshibák lehetséges forrását jelenti.

A metódusban DemonstrateProblemUsingCanThrow bemutatott első probléma az, hogy a záró kapcsos zárójel kivételt okoz, és a záró zárójel utáni kód nem fut:

using (CalculatorClient client = new CalculatorClient())
{
    ...
} // <-- this line might throw
Console.WriteLine("Hope this code wasn't important, because it might not happen.");

Még akkor sem, ha a használatban lévő blokkon belül semmi sem jelez kivételt, vagy a használatblokkon belüli összes kivétel ki van fogott, előfordulhat Console.WriteLine , hogy nem történik meg, mert a záró zárójel implicit Dispose() hívása kivételt okozhat.

A módszerben DemonstrateProblemUsingCanThrowAndMask bemutatott második probléma a záró zárójel kivételt eredményező másik következménye:

using (CalculatorClient client = new CalculatorClient())
{
    ...
    throw new ApplicationException("Hope this exception was not important, because "+
                                   "it might be masked by the Close exception.");
} // <-- this line might throw an exception.

Mivel a Dispose() egy "végre" blokkon belül történik, a ApplicationException rendszer soha nem jelenik meg a használaton kívül, ha a Dispose() sikertelen. Ha a külső kódnak tudnia kell, ApplicationException hogy mikor fordul elő, a "használat" szerkezet problémákat okozhat a kivétel maszkolásával.

Végül a minta bemutatja, hogyan lehet helyesen megtisztítani a kivételeket.DemonstrateCleanupWithExceptions Ez egy próba/fogási blokkot használ a hibák és hívások Abortjelentéséhez. Az ügyfélhívások kivételeinek befogásával kapcsolatos további részletekért tekintse meg a Várt kivételek mintát.

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

Feljegyzés

Az using utasítás és ServiceHost: Sok önkiszolgáló alkalmazás alig több, mint egy szolgáltatás üzemeltetése, és ServiceHost.Close ritkán kivételt vet ki, így az ilyen alkalmazások biztonságosan használhatják az using utasítást ServiceHost. Vegye figyelembe azonban, hogy ServiceHost.Close ez okozhatja CommunicationExceptiona hibát, ezért ha az alkalmazás a ServiceHostbezárása után is folytatódik, kerülje az utasítást using , és kövesse a korábban megadott mintát.

A minta futtatásakor a műveleti válaszok és a kivételek megjelennek az ügyfélkonzol ablakában.

Az ügyfélfolyamat három forgatókönyvet futtat, amelyek mindegyike megpróbál meghívni Divide. Az első forgatókönyv azt mutatja be, hogy a kód kihagyása a () kivétel Disposemiatt történik. A második forgatókönyv egy fontos kivétel maszkolását mutatja be egy () kivétel Disposemiatt. A harmadik forgatókönyv a helyes tisztítást mutatja be.

Az ügyfélfolyamat várt kimenete a következő:

=
= Demonstrating problem:  closing brace of using statement can throw.
=
Got System.ServiceModel.CommunicationException from Divide.
Got System.ServiceModel.Security.MessageSecurityException
=
= Demonstrating problem:  closing brace of using statement can mask other Exceptions.
=
Got System.ServiceModel.CommunicationException from Divide.
Got System.ServiceModel.Security.MessageSecurityException
=
= Demonstrating cleanup with Exceptions.
=
Calling client.Add(0.0, 0.0);
        client.Add(0.0, 0.0); returned 0
Calling client.Divide(0.0, 0.0);
Got System.ServiceModel.CommunicationException from Divide.

Press <ENTER> to terminate client.

A minta beállítása, összeállítása és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.

  2. A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse a Windows Communication Foundation-minták készítéséhez szükséges utasításokat.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse a Windows Communication Foundation-minták futtatásával kapcsolatos utasításokat.