Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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 k příslušné operaci služby nebo běžícímu klientskému 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
Použijte asynchronní přístup v implementaci operace služby, pokud implementace operace služby provede blokující operaci, jako je například vstupně-výstupní práce. Pokud pracujete na implementaci asynchronní operace, snažte se volat asynchronní operace a metody a rozšířit asynchronní cestu volání co nejdále. Můžete například volat BeginOperationTwo() zevnitř BeginOperationOne().
Použijte asynchronní přístup v klientských nebo volajících aplikacích 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 modelu vyvolávání založeného na událostech se událost výsledku vyvolá ve vlákně uživatelského rozhraní, čímž se zvyšuje responzivita aplikace, aniž byste museli spravovat vlákna 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:
Asynchronní vzor založený na úlohách
Asynchronní vzor založený na událostech
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í Task<string>, 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.
Upozornění
Při použití asynchronního vzoru založeného na úlohách může být vyvolána 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é událost MethodNameCompleted a může mít metodu MethodNameAsyncCancel (nebo jednoduše CancelAsync). Klient, který chce operaci zavolat, nastaví obslužnou rutinu události, jež se má spustit 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 vzor mohou reprezentovat jako synchronní operaci nebo jako asynchronní operaci, pokud je při vyvolání služby provedena výměna zpráv typu žádost-odpověď.
Obecně platí, že s asynchronní povahou systémů byste neměli záviset na vláknech. Nejspolehlivější způsob, jak předávat data do různých fází zpracování řízení operací, je použít 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
BeginOperationaEndOperation.Metoda
BeginOperationobsahujeinarefparametry operace a vrací IAsyncResult typ.Tato
EndOperationmetoda obsahuje IAsyncResult parametr ioutparametry arefvrací 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 Jak na to: 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áno ani v rozhraní .NET Framework 3.5, když je klientský kanál WCF vytvořen pomocí System.ServiceModel.ChannelFactory<TChannel>. 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. Pro úplný příklad použití ChannelFactory<TChannel> viz Návod na volání operací asynchronně pomocí Channel Factory (továrny na kanály).
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 lze jednosměrné operace (operace, pro které OperationContractAttribute.IsOneWaytrue nejsou korelované odpovědi) odesílat oběma směry, a to buď klientem, nebo službou nezávisle na druhé straně. (Používá se duplexní vzor 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 jedna ze stran implementovat buď jako asynchronní volání nebo jako implementace, nebo to může být podle potřeby výslovně neimplementováno. 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 asynchronního modelu založeného na událostech uvádějí, že pokud je vráceno více než jedna hodnota, jedna hodnota se vrátí jako vlastnost Result a ostatní 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ímto se vygeneruje podpis, který vrací odpověď formou zprávy jako vlastnost Result na objektu EventArgs. Všechny interní návratové hodnoty jsou vlastnosti objektu zprávy odpovědi.