Synchronní a asynchronní operace

Toto téma popisuje implementaci a volání asynchronních operací služby.

Mnoho aplikací volá metody asynchronně, protože umožňuje aplikaci pokračovat v práci, zatímco volání metody běží. Služby a klienti windows Communication Foundation (WCF) se mohou účastnit asynchronních volání operací na dvou různých úrovních aplikace, které poskytují aplikacím WCF ještě větší flexibilitu, aby se maximalizovala propustnost vyvážená proti interaktivitě.

Typy asynchronních operací

Všechny kontrakty služeb v WCF bez ohledu na typy parametrů a návratové hodnoty používají atributy WCF k určení konkrétního vzoru výměny zpráv mezi klientem a službou. WCF automaticky směruje příchozí a odchozí zprávy do příslušné operace služby nebo spuštění klientského kódu.

Klient má pouze kontrakt služby, který určuje způsob výměny zpráv pro konkrétní operaci. Klienti můžou vývojáři nabídnout libovolný programovací model, který zvolí, pokud je zjištěn základní vzor výměny zpráv. Proto mohou služby implementovat operace jakýmkoli způsobem, pokud je zjištěn zadaný vzor zpráv.

Nezávislost kontraktu služby od implementace služby nebo klienta umožňuje následující formy asynchronního spouštění v aplikacích WCF:

  • Klienti mohou asynchronně vyvolat operace požadavků a odpovědí pomocí synchronní výměny zpráv.

  • Služby můžou implementovat operaci žádosti a odpovědi asynchronně pomocí synchronní výměny zpráv.

  • Výměny zpráv můžou být jednosměrné bez ohledu na implementaci klienta nebo služby.

Navrhované asynchronní scénáře

Pokud implementace provozní služby provede blokující volání, jako je například vstupně-výstupní operace, použijte asynchronní přístup v implementaci operace. Pokud jste v implementaci asynchronní operace, pokuste se volat asynchronní operace a metody rozšířit asynchronní cestu volání co nejvíce. Můžete například volat BeginOperationTwo() z uvnitř BeginOperationOne().

  • Použití asynchronního přístupu v klientovi nebo volání aplikace v následujících případech:

  • Pokud vyvoláváte operace z aplikace střední vrstvy. (Další informace o takových scénářích najdete v tématu Klientské aplikace střední vrstvy.)

  • Pokud vyvoláváte operace na stránce ASP.NET, použijte asynchronní stránky.

  • Pokud vyvoláváte operace z jakékoli aplikace, která je tvořena jedním vláknem, jako je model Windows Forms nebo Windows Presentation Foundation (WPF). Při použití asynchronního volajícího modelu založeného na událostech se událost výsledku vyvolá ve vlákně uživatelského rozhraní a přidá do aplikace rychlost odezvy, aniž byste museli zpracovat více vláken sami.

  • Obecně platí, že pokud máte volbu mezi synchronním a asynchronním voláním, zvolte asynchronní volání.

Implementace asynchronní operace služby

Asynchronní operace je možné implementovat pomocí jedné ze tří následujících metod:

  1. Asynchronní vzor založený na úlohách

  2. Asynchronní vzor založený na událostech

  3. Asynchronní vzor IAsyncResult

Asynchronní vzor založený na úlohách

Asynchronní vzor založený na úlohách je upřednostňovaným způsobem implementace asynchronních operací, protože je nejjednodušší a nejpřímější. Chcete-li použít tuto metodu, jednoduše implementujte operaci služby a zadejte návratový typ úlohy<T>, kde T je typ vrácený logickou operací. Příklad:

public class SampleService:ISampleService
{
   // ...  
   public async Task<string> SampleMethodTaskAsync(string msg)
   {
      return Task<string>.Factory.StartNew(() =>
      {
         return msg;
      });
   }  
   // ...  
}  

Operace SampleMethodTaskAsync vrátí řetězec> úlohy<, protože logická operace vrací řetězec. Další informace o asynchronním vzoru založeném na úlohách naleznete v tématu Asynchronní vzor založený na úlohách.

Upozorňující

Při použití asynchronního vzoru založeného na úlohách může být vyvolán výjimka T:System.AggregateException, pokud dojde k výjimce při čekání na dokončení operace. K této výjimce může dojít u klienta nebo služeb.

Asynchronní vzor založený na událostech

Služba, která podporuje asynchronní vzor založený na událostech, bude mít jednu nebo více operací s názvem MethodNameAsync. Tyto metody mohou zrcadlit synchronní verze, které provádějí stejnou operaci v aktuálním vlákně. Třída může mít také MethodNameCompleted událost a může mít MethodNameAsyncCancel (nebo jednoduše CancelAsync) metoda. Klient, který chce operaci volat, definuje obslužnou rutinu události, která se má volat po dokončení operace.

Následující fragment kódu ukazuje, jak deklarovat asynchronní operace pomocí asynchronního vzoru založeného na událostech.

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.  
}  

Další informace o asynchronním vzoru založeném na událostech naleznete v tématu Asynchronní vzor založený na událostech.

Asynchronní vzor IAsyncResult

Operaci služby lze implementovat asynchronním způsobem pomocí asynchronního programovacího vzoru rozhraní .NET Framework a označení <Begin> metody s vlastností nastavenou AsyncPattern na true. V tomto případě je asynchronní operace vystavena v metadatech ve stejné podobě jako synchronní operace: Je vystavena jako jedna operace se zprávou požadavku a korelační zprávou odpovědi. Klientské programovací modely pak mají na výběr. Tento model mohou představovat jako synchronní operaci nebo jako asynchronní operaci, pokud se služba vyvolána výměnou zpráv s žádostí a odpovědí.

Obecně platí, že s asynchronní povahou systémů byste neměli brát závislost na vláknech. Nejspolehlivější způsob předávání dat do různých fází zpracování odesílání operací je použití rozšíření.

Příklad najdete v tématu Postupy: Implementace asynchronní operace služby.

Definování operace X kontraktu, která se spouští asynchronně bez ohledu na to, jak se volá v klientské aplikaci:

  • Definujte dvě metody pomocí vzoru BeginOperation a EndOperation.

  • Metoda BeginOperation obsahuje in a ref parametry operace a vrací IAsyncResult typ.

  • Tato EndOperation metoda obsahuje IAsyncResult parametr i out parametry a ref vrací návratový typ operací.

Podívejte se například na následující metodu.

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  

Chcete-li vytvořit asynchronní operaci, budou dvě metody:

[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  

Poznámka:

Atribut OperationContractAttribute je použit pouze pro metodu BeginDoWork . Výsledný kontrakt má jednu operaci WSDL s názvem DoWork.

Asynchronní vyvolání na straně klienta

Klientská aplikace WCF může používat libovolný ze tří asynchronních modelů volání popsaných výše.

Při použití modelu založeného na úlohách jednoduše zavolejte operaci pomocí klíčového slova await, jak je znázorněno v následujícím fragmentu kódu.

await simpleServiceClient.SampleMethodTaskAsync("hello, world");  

Použití asynchronního vzoru založeného na událostech vyžaduje pouze přidání obslužné rutiny události pro příjem oznámení odpovědi a výsledná událost se vyvolá v vlákně uživatelského rozhraní automaticky. Pokud chcete tento přístup použít, zadejte možnosti příkazu /async i /tcv:Version35 pomocí nástroje ServiceModel Metadata Utility (Svcutil.exe) jako v následujícím příkladu.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async /tcv:Version35  

Po dokončení Svcutil.exe vygeneruje klientskou třídu WCF s infrastrukturou událostí, která volající aplikaci umožňuje implementovat a přiřadit obslužnou rutinu události k přijetí odpovědi a provedení příslušné akce. Úplný příklad najdete v tématu Postupy: Asynchronní volání operací služby.

Asynchronní model založený na událostech je však k dispozici pouze v rozhraní .NET Framework 3.5. Kromě toho není podporována ani v rozhraní .NET Framework 3.5 při vytvoření klientského kanálu WCF pomocí System.ServiceModel.ChannelFactory<TChannel>rozhraní . U objektů klientského kanálu WCF je nutné použít System.IAsyncResult objekty k asynchronnímu vyvolání operací. Pokud chcete tento přístup použít, zadejte možnost příkazu /async pomocí nástroje ServiceModel Metadata Utility (Svcutil.exe) jako v následujícím příkladu.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async

Tím se vygeneruje kontrakt služby, ve kterém je každá operace modelována jako <Begin> metoda s AsyncPattern vlastností nastavenou na true a odpovídající <End> metodou. Úplný příklad použití ChannelFactory<TChannel>, viz Postupy: Volání operací asynchronně pomocí objektu pro vytváření kanálů.

V obou případech můžou aplikace vyvolat operaci asynchronně i v případě, že je služba implementována synchronně, stejným způsobem jako aplikace může použít stejný vzor k asynchronnímu vyvolání místní synchronní metody. Způsob implementace operace není pro klienta významný; jakmile zpráva odpovědi přijde, její obsah se odešle do asynchronní <End> metody klienta a klient načte informace.

Jednosměrné vzory výměny zpráv

Můžete také vytvořit asynchronní vzor výměny zpráv, ve kterém klient nebo služba může odesílat jednosměrné operace (operace, pro které OperationContractAttribute.IsOneWaytrue nejsou korelované odpovědi), a to buď směrem, klientem nebo službou nezávisle na druhé straně. (Používá se vzor oboustranné výměny zpráv s jednosměrnými zprávami.) V tomto případě kontrakt služby určuje jednosměrnou výměnu zpráv, kterou může obě strany implementovat jako asynchronní volání nebo implementace, nebo ne, podle potřeby. Obecně platí, že když je kontrakt výměnou jednosměrných zpráv, implementace mohou být z velké části asynchronní, protože po odeslání zprávy aplikace nečeká na odpověď a může pokračovat v práci.

Asynchronní klienti a kontrakty zpráv založené na událostech

Pokyny k návrhu pro stav asynchronního modelu založeného na událostech, že pokud je vrácena více než jedna hodnota, vrátí se jedna hodnota jako Result vlastnost a ostatní se vrátí jako vlastnosti objektu EventArgs . Jedním z těchto výsledků je, že pokud klient importuje metadata pomocí možností asynchronního příkazu založeného na událostech a operace vrátí více než jednu hodnotu, výchozí EventArgs objekt vrátí jednu hodnotu jako Result vlastnost a zbytek jsou vlastnosti objektu EventArgs .

Chcete-li přijmout objekt zprávy jako Result vlastnost a mít vrácené hodnoty jako vlastnosti tohoto objektu, použijte možnost příkazu /messageContract . Tím se vygeneruje podpis, který vrátí zprávu odpovědi jako Result vlastnost objektu EventArgs . Všechny interní návratové hodnoty jsou vlastnosti objektu zprávy odpovědi.

Viz také