Szinkron és aszinkron műveletek
Ez a témakör az aszinkron szolgáltatásműveletek implementálását és meghívását ismerteti.
Sok alkalmazás aszinkron módon hívja meg a metódusokat, mert így az alkalmazás továbbra is hasznos munkát végezhet a metódushívás futtatása közben. A Windows Communication Foundation (WCF) szolgáltatásai és ügyfelei az alkalmazás két különböző szintjén is részt vehetnek az aszinkron művelethívásokban, ami még nagyobb rugalmasságot biztosít a WCF-alkalmazások számára az interaktivitással kiegyensúlyozott átviteli sebesség maximalizálása érdekében.
Aszinkron műveletek típusai
A WCF összes szolgáltatási szerződése– a paraméterek típusának és a visszaadott értékektől függetlenül – WCF-attribútumokkal határoz meg egy adott üzenetváltási mintát az ügyfél és a szolgáltatás között. A WCF automatikusan átirányítja a bejövő és kimenő üzeneteket a megfelelő szolgáltatásművelethez vagy az ügyfélkód futtatásához.
Az ügyfél csak a szolgáltatási szerződéssel rendelkezik, amely egy adott művelet üzenetváltási mintáját határozza meg. Az ügyfelek bármilyen programozási modellt kínálhatnak a fejlesztőnek, amelyet választanak, amíg a mögöttes üzenetcsere-minta meg nem figyelhető. Így a szolgáltatások is bármilyen módon implementálhatják a műveleteket, amíg a megadott üzenetmintát betartják.
A szolgáltatási szerződésnek a szolgáltatástól vagy ügyfél-megvalósítástól való függetlensége lehetővé teszi az aszinkron végrehajtás következő formáit a WCF-alkalmazásokban:
Az ügyfelek szinkron üzenetcserével aszinkron módon hívhatják meg a kérés- és válaszműveleteket.
A szolgáltatások szinkron üzenetcsere használatával aszinkron módon implementálhatnak kérés-válasz műveletet.
Az üzenetváltások egyirányúak lehetnek, függetlenül az ügyfél vagy szolgáltatás implementálásától.
Javasolt aszinkron forgatókönyvek
Használjon aszinkron megközelítést egy szolgáltatásművelet-implementációban, ha a műveleti szolgáltatás implementációja blokkoló hívást kezdeményez, például I/O-munkát végez. Ha aszinkron művelet megvalósításában van, próbálja meg meghívni az aszinkron műveleteket és metódusokat az aszinkron hívási útvonal lehető legnagyobb kiterjesztése érdekében. Hívja meg például a belülről BeginOperationOne()
érkezőtBeginOperationTwo()
.
Használjon aszinkron megközelítést egy ügyfélben vagy egy alkalmazás hívásához a következő esetekben:
Ha középső szintű alkalmazásból invoktál műveleteket. (További információ az ilyen forgatókönyvekről: Középső szintű ügyfélalkalmazások.)
Ha egy ASP.NET lapon belüli műveleteket invoktál, használjon aszinkron oldalakat.
Ha egyszálas alkalmazásból, például Windows Formsból vagy Windows megjelenítési alaprendszer (WPF) származó műveleteket kér le. Az eseményalapú aszinkron hívási modell használatakor az eredményesemény a felhasználói felületi szálon jön létre, és válaszképességet ad az alkalmazásnak anélkül, hogy több szálat kellene kezelnie.
Általánosságban elmondható, hogy ha a szinkron és az aszinkron hívás között választhat, válassza ki az aszinkron hívást.
Aszinkron szolgáltatásművelet implementálása
Az aszinkron műveletek az alábbi három módszer egyikével implementálhatók:
A tevékenységalapú aszinkron minta
Az eseményalapú aszinkron minta
Az IAsyncResult aszinkron minta
Feladatalapú aszinkron minta
A feladatalapú aszinkron minta az aszinkron műveletek implementálásának előnyben részesített módja, mivel ez a legegyszerűbb és legegyértelműbb. A metódus használatához egyszerűen implementálja a szolgáltatásműveletet, és adja meg a T> feladat<visszatérési típusát, ahol a T a logikai művelet által visszaadott típus. Példa:
public class SampleService:ISampleService
{
// ...
public async Task<string> SampleMethodTaskAsync(string msg)
{
return Task<string>.Factory.StartNew(() =>
{
return msg;
});
}
// ...
}
A SampleMethodTaskAsync művelet feladatsztringet<> ad vissza, mert a logikai művelet egy sztringet ad vissza. A tevékenységalapú aszinkron mintával kapcsolatos további információkért lásd a tevékenységalapú aszinkron mintát.
Figyelmeztetés
A feladatalapú aszinkron minta használata esetén T:System.AggregateException akkor jelenhet meg, ha kivétel történik a művelet befejezésére való várakozás közben. Ez a kivétel az ügyfélen vagy a szolgáltatásokon fordulhat elő
Eseményalapú aszinkron minta
Az eseményalapú aszinkron mintát támogató szolgáltatás egy vagy több MethodNameAsync nevű művelettel rendelkezik. Ezek a metódusok tükrözhetik a szinkron verziókat, amelyek ugyanazt a műveletet hajtják végre az aktuális szálon. Az osztály rendelkezhet MethodNameCompleted eseménysel is, és lehet, hogy methodNameAsyncCancel (vagy egyszerűen CancelAsync) metódussal rendelkezik. A műveletet meghívni kívánó ügyfél meghatároz egy eseménykezelőt, amelyet a művelet befejezésekor kell meghívni.
Az alábbi kódrészlet bemutatja, hogyan deklarálhat aszinkron műveleteket az eseményalapú aszinkron mintával.
public class AsyncExample
{
// Synchronous methods.
public int Method1(string param);
public void Method2(double param);
// Asynchronous methods.
public void Method1Async(string param);
public void Method1Async(string param, object userState);
public event Method1CompletedEventHandler Method1Completed;
public void Method2Async(double param);
public void Method2Async(double param, object userState);
public event Method2CompletedEventHandler Method2Completed;
public void CancelAsync(object userState);
public bool IsBusy { get; }
// Class implementation not shown.
}
Az eseményalapú aszinkron mintával kapcsolatos további információkért lásd : Az eseményalapú aszinkron minta.
IAsyncResult Aszinkron minta
A szolgáltatásművelet aszinkron módon implementálható az .NET-keretrendszer aszinkron programozási mintával, és megjelölheti a <Begin>
metódust true
a AsyncPattern következő tulajdonsággal: . Ebben az esetben az aszinkron művelet a metaadatokban a szinkron művelettel megegyező formában jelenik meg: Egyetlen műveletként jelenik meg egy kérelemüzenettel és egy korrelált válaszüzenettel. Az ügyfélprogramozási modelleknek ezután van választási lehetőségük. Ezt a mintát szinkron műveletként vagy aszinkron műveletként jelölhetik, mindaddig, amíg a szolgáltatás meghívásakor kérés-válasz üzenetcserére kerül sor.
Általánosságban elmondható, hogy a rendszerek aszinkron jellegével nem szabad függőséget vállalnia a szálaktól. Az adatok továbbításának legmegbízhatóbb módja a műveletküldés különböző szakaszainak a bővítmények használata.
Példa: Útmutató: Aszinkron szolgáltatásművelet implementálása.
Az aszinkron módon végrehajtott szerződésművelet X
definiálása az ügyfélalkalmazásban való meghívástól függetlenül:
Definiáljon két metódust a mintával
BeginOperation
ésEndOperation
a .A
BeginOperation
metódus tartalmazzain
a művelet paramétereit,ref
és egy típust IAsyncResult ad vissza.A
EndOperation
metódus tartalmaz egy paramétert IAsyncResult , valamint aout
paramétereket,ref
és visszaadja a műveletek visszatérési típusát.
Lásd például a következő módszert.
int DoWork(string data, ref string inout, out string outonly)
Function DoWork(ByVal data As String, ByRef inout As String, _out outonly As out) As Integer
Aszinkron művelet létrehozásához a két módszer a következő:
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginDoWork(string data,
ref string inout,
AsyncCallback callback,
object state);
int EndDoWork(ref string inout, out string outonly, IAsyncResult result);
<OperationContract(AsyncPattern := True)>
Function BeginDoWork(ByVal data As String, _
ByRef inout As String, _
ByVal callback As AsyncCallback, _
ByVal state As Object) As IAsyncResult
Function EndDoWork(ByRef inout As String, ByRef outonly As String, ByVal result As IAsyncResult) As Integer
Feljegyzés
Az OperationContractAttribute attribútum csak a BeginDoWork
metódusra lesz alkalmazva. Az eredményként kapott szerződés egy WSDL-művelettel rendelkezik.DoWork
Ügyféloldali aszinkron meghívások
A WCF-ügyfélalkalmazások a korábban ismertetett három aszinkron hívási modell bármelyikét használhatják
A feladatalapú modell használatakor egyszerűen hívja meg a műveletet a vár kulcsszó használatával, ahogyan az az alábbi kódrészletben látható.
await simpleServiceClient.SampleMethodTaskAsync("hello, world");
Az eseményalapú aszinkron minta használatához csak egy eseménykezelő hozzáadása szükséges a válaszról szóló értesítés fogadásához , és az eredményül kapott esemény automatikusan megjelenik a felhasználói felület szálán. Ennek a módszernek a használatához adja meg a /async és a /tcv:Version35 parancsbeállításokat a ServiceModel Metadata segédprogrammal (Svcutil.exe) az alábbi példához hasonlóan.
svcutil http://localhost:8000/servicemodelsamples/service/mex /async /tcv:Version35
Ha ez megtörtént, Svcutil.exe létrehoz egy WCF-ügyfélosztályt az eseményinfrastruktúrával, amely lehetővé teszi a hívó alkalmazás számára, hogy megvalósítsa és hozzárendeljen egy eseménykezelőt a válasz fogadásához és a megfelelő művelet végrehajtásához. Egy teljes példa : A szolgáltatásműveletek aszinkron meghívása.
Az eseményalapú aszinkron modell azonban csak a .NET-keretrendszer 3.5-ben érhető el. Emellett még a 3.5-ös .NET-keretrendszer sem támogatott, ha WCF-ügyfélcsatorna jön létre egy System.ServiceModel.ChannelFactory<TChannel>. WCF-ügyfélcsatorna-objektumok esetén System.IAsyncResult objektumokkal kell aszinkron módon meghívni a műveleteket. Ennek a módszernek a használatához adja meg a /async parancsot a ServiceModel Metadata Segédprogrammal (Svcutil.exe) az alábbi példához hasonlóan.
svcutil http://localhost:8000/servicemodelsamples/service/mex /async
Ez létrehoz egy szolgáltatási szerződést, amelyben a rendszer minden egyes műveletet metódusként <Begin>
modellel, amelynek a tulajdonsága true
AsyncPattern és egy megfelelő <End>
metódusa van. Egy teljes példát a ChannelFactory<TChannel>Channel Factory használatával: Hogyan hívhatja meg az aszinkron műveleteket a Channel Factory használatával.
Az alkalmazások mindkét esetben aszinkron módon hívhatnak meg egy műveletet, még akkor is, ha a szolgáltatás szinkron módon van implementálva, ugyanúgy, ahogyan egy alkalmazás ugyanazt a mintát használhatja a helyi szinkron metódus aszinkron meghívásához. A művelet implementálása nem lényeges az ügyfél számára; amikor megérkezik a válaszüzenet, annak tartalma el lesz küldve az ügyfél aszinkron <End
> metódusának, és az ügyfél lekéri az információkat.
Egyirányú üzenetváltási minták
Aszinkron üzenetcseremintát is létrehozhat, amelyben az egyirányú műveleteket (amelyekhez OperationContractAttribute.IsOneWaytrue
nincs korrelált válasz) az ügyfél vagy a szolgáltatás a másik oldaltól függetlenül bármelyik irányban elküldheti. (Ez a kétirányú üzenetváltási mintát használja egyirányú üzenetekkel.) Ebben az esetben a szolgáltatási szerződés egy egyirányú üzenetcserét határoz meg, amelyet bármelyik fél aszinkron hívásként vagy implementációként implementálhat, vagy nem, ha szükséges. Általában, ha a szerződés egyirányú üzenetek cseréje, a megvalósítások nagyrészt aszinkronok lehetnek, mivel az üzenet elküldése után az alkalmazás nem várja meg a választ, és folytathatja a további munkát.
Eseményalapú aszinkron ügyfelek és üzenetszerződések
Az eseményalapú aszinkron modell tervezési irányelvei szerint ha egynél több értéket ad vissza, a rendszer egy értéket ad vissza tulajdonságként Result
, a többit pedig tulajdonságokként az EventArgs objektumon. Ennek egyik eredménye, hogy ha egy ügyfél az eseményalapú aszinkron parancsbeállítások használatával importál metaadatokat, és a művelet több értéket ad vissza, az alapértelmezett EventArgs objektum egy értéket ad vissza tulajdonságként Result
, a többi pedig az EventArgs objektum tulajdonságait.
Ha tulajdonságként szeretné megkapni az Result
üzenetobjektumot, és a visszaadott értékeket tulajdonságokként szeretné megkapni az objektumon, használja a /messageContract parancsot. Ez létrehoz egy aláírást, amely visszaadja a válaszüzenetet az Result
objektum tulajdonságaként EventArgs . Ezután az összes belső visszatérési érték a válaszüzenet-objektum tulajdonságai.