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 Dispose
eredményezi. Ez ugyanaz, mint Close
(), amely kivételeket okozhat hálózati hiba esetén. Mivel a () hívása Dispose
implicit 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 Abort
jelenté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 CommunicationException
a hibát, ezért ha az alkalmazás a ServiceHost
bezá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 Dispose
miatt történik. A második forgatókönyv egy fontos kivétel maszkolását mutatja be egy () kivétel Dispose
miatt. 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
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.
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.
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.