Programování

Učení SynchronizationContext, asynchronizace a čekání

Asynchronní programování je forma paralelního programování, která vám umožňuje provádět úkoly odděleně od hlavního vlákna aplikace a poté vlákno upozorní, když jeho spuštění skončí. Asynchrony vám pomůže provádět úkoly bez nutnosti zdržet se průběhu provádění nebo odezvy vaší aplikace.

Microsoft poskytl podporu pro paralelní programování v .Net Framework, aby využil výhody vícejádrových systémů. Asynchrony můžete využít ke zlepšení výkonu a odezvy vaší aplikace.

V podstatě existují dva možné typy operací v aplikaci. Patří mezi ně operace vázané na výpočet a I / O. Operace vázané na výpočet jsou ty, ve kterých lze výpočet provádět na samostatném vlákně, aby hlavní vlákno mohlo pokračovat ve svém provádění. Naopak, I / O vázané operace jsou ty, ve kterých jsou prováděny externě, a proto nepotřebují blokovat aktuální vlákno, zatímco I / O probíhá.

Kontext synchronizace a kontext provádění

Každé vlákno má přidružený kontext - toto se také nazývá „aktuální“ kontext - a tyto kontexty lze sdílet napříč vlákny. ExecutionContext obsahuje relevantní metadata aktuálního prostředí nebo kontextu, ve kterém je program v provádění. SynchronizationContext představuje abstrakci - označuje umístění, kde je spuštěn kód vaší aplikace.

SynchronizationContext vám umožňuje zařadit úkol do jiného kontextu. Všimněte si, že každé vlákno může mít svůj vlastní SynchronizatonContext. Třída SynchronizationContext byla nedávno přidána do oboru názvů System.Threading a usnadňuje komunikaci mezi vlákny. Další informace o SynchronizationContext a ExecutionContext si můžete přečíst zde.

Hluboký ponor uvnitř Async a Await

Tři vzory asynchronního programování zahrnují následující:

  1. Model asynchronního programování (APM)
  2. Událostní asynchronní vzor (EAP)
  3. Asynchronní vzor založený na úlohách (TAP)

Nejnovějším, doporučeným a také nejelegantnějším z nich je TAP.

Metodu můžete označit pomocí klíčového slova „asynchronní“, které vrací void, Task nebo Task. Všimněte si, že když dojde k výjimce uvnitř asynchronní metody, která má návratový typ Task nebo Task, podrobnosti výjimky jsou uloženy uvnitř Task instance.

Naopak, když dojde k výjimce uvnitř asynchronní metody, která má návratový typ void, podrobnosti výjimky jsou uloženy uvnitř SynchronizationContext, který byl aktivní v době, kdy byla asynchronní metoda volána. V podstatě nemůžete zpracovat výjimky vyvolané v asynchronní metodě, která má návratový typ void pomocí obslužných rutin výjimek zapsaných uvnitř asynchronní metody. Z důvodu různé sémantiky výpočetní techniky a zpracování chyb je vhodné vyhnout se asynchronním metodám, které mají neplatné návratové typy, pokud není dostatečný důvod k jejich použití.

Když použijete klíčové slovo "await" uvnitř asynchronní metody, je metoda rozdělena uvnitř stavového stroje. Všimněte si, že klíčové slovo "await" zachycuje aktuální SynchronizationContext a jakmile je dokončen úkol, který byl očekáván pomocí klíčového slova "await", stavový stroj je obnoven a spuštění kódu v metodě volajícího se restartuje - to je také pokračování. Pokud bylo v době, kdy dojde k bodu pozastavení, dokončeno provádění kódu, který byl očekáván pomocí klíčového slova „await“, provede se synchronně asynchronní metoda (metoda, která byla označena jako „async“). Pokud provedení kódu, na který se očekávalo, není dokončeno, je ke kódu, na který se čeká, připojen delegát pokračování.

Můžete využít výhod asynchronních metod, které vrátí void, k vytvoření obslužných rutin asynchronních událostí. Metodu Main nelze označit klíčovým slovem „async“, protože je vstupním bodem aplikace - metoda „async“ Main by byla ukončena v okamžiku jejího volání. Klíčové slovo „await“ informuje kompilátor, že metoda může mít bod pozastavení a obnovení. Mimochodem, klíčové slovo „await“ můžete použít pouze u metody, která byla označena jako asynchronní pomocí klíčového slova „async“.

Asynchronní metoda při volání běží synchronně na aktuální vlákno bez ohledu na návratový typ metody. Když označíte metodu jako asynchronní pomocí klíčového slova „async“, informujete pouze kompilátor, že metodu lze rozdělit na více úkolů - některé z těchto úkolů se mohou provádět asynchronně. Zahrnutí klíčového slova „asynchronní“ do metody také nezaradí frontu vyvolání metody jako součást fondu vláken. Asynchronie (tj. Zda by metoda měla asynchronní chování) ve skutečnosti závisí na bodě pozastavení, který jste uvedli ve své metodě pomocí klíčového slova „await“. Pokud do asynchronní metody nezadáte klíčové slovo „await“, celá metoda se provede synchronně.