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


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:

  1. A tevékenységalapú aszinkron minta

  2. Az eseményalapú aszinkron minta

  3. 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 truea 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 és EndOperationa .

  • A BeginOperation metódus tartalmazza in a művelet paramétereit, ref és egy típust IAsyncResult ad vissza.

  • A EndOperation metódus tartalmaz egy paramétert IAsyncResult , valamint a out 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 trueAsyncPattern é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.

Lásd még