Sdílet prostřednictvím


Shrnutí kapitoly 20. Asynchronní a souborové I/O

Poznámka:

Tato kniha byla publikována na jaře roku 2016 a od té doby nebyla aktualizována. Existuje mnoho v knize, která zůstává cenná, ale některé materiály jsou zastaralé a některá témata už nejsou zcela správná nebo úplná.

Grafické uživatelské rozhraní musí reagovat na události vstupu uživatele postupně. To znamená, že veškeré zpracování událostí uživatelského vstupu musí nastat v jednom vlákně, často označované jako hlavní vlákno nebo vlákno uživatelského rozhraní.

Uživatelé očekávají, že grafická uživatelská rozhraní budou responzivní. To znamená, že program musí rychle zpracovávat události uživatelského vstupu. Pokud to není možné, musí být zpracování přelegováno na sekundární vlákna provádění.

V této knize bylo použito WebRequest několik ukázkových programů. V této třídě BeginGetResponse metoda spustí pracovní vlákno, které volá funkci zpětného volání po dokončení. Tato funkce zpětného volání však běží v pracovním vlákně, takže program musí volat Device.BeginInvokeOnMainThread metodu pro přístup k uživatelskému rozhraní.

Poznámka:

Xamarin.Forms programy by neměly používat HttpClient místo WebRequest přístupu k souborům přes internet. HttpClient podporuje asynchronní operace.

Modernější přístup k asynchronnímu zpracování je k dispozici v .NET a C#. To zahrnuje třídy Task a Task<TResult> další typy v oborech System.Threading názvů a System.Threading.Tasks také jazyk C# 5.0 async a await klíčová slova. To je to, na co se tato kapitola zaměřuje.

Od zpětného volání do operátoru await

Samotná Page třída obsahuje tři asynchronní metody pro zobrazení polí výstrah:

Objekty Task označují, že tyto metody implementují asynchronní vzor založený na úlohách, označovaný jako TAP. Tyto Task objekty jsou rychle vráceny z metody. Návratové Task<T> hodnoty představují "příslib", že hodnota typu TResult bude k dispozici po dokončení úkolu. Vrácená Task hodnota označuje asynchronní akci, která se dokončí, ale bez vrácené hodnoty.

Ve všech těchtopřípadechch Task

Upozornění se zpětnými voláními

Ukázka AlertCallbacks ukazuje, jak zpracovat Task<bool> návratové objekty a Device.BeginInvokeOnMainThread volání pomocí metod zpětného volání.

Upozornění s lambdami

Ukázka AlertLambdas ukazuje, jak používat anonymní funkce lambda pro zpracování Task a Device.BeginInvokeOnMainThread volání.

Výstraha s operátorem Await

Jednodušší přístup zahrnuje async await klíčová slova představená v jazyce C# 5. Ukázka AlertAwait ukazuje jejich použití.

Upozornění s nic

Pokud asynchronní metoda vrátí Task místo Task<TResult>, pak program nemusí používat žádné z těchto technik, pokud nepotřebuje vědět, kdy asynchronní úkol dokončí. Ukázka NothingAlert ukazuje tuto akci.

Asynchronní ukládání nastavení programu

Ukázka SaveProgramChanges ukazuje použití SavePropertiesAsync metody Application uložení nastavení programu při jejich změně bez přepsání OnSleep metody.

Časovač nezávislý na platformě

Je možné použít Task.Delay k vytvoření časovače nezávislého na platformě. Ukázka TaskDelayClock ukazuje tuto možnost.

Vstup/výstup souboru

Tradičně byl obor názvů .NET System.IO zdrojem podpory vstupně-výstupních operací souborů. I když některé metody v tomto oboru názvů podporují asynchronní operace, většina ne. Obor názvů také podporuje několik jednoduchých volání metod, která provádějí sofistikované vstupně-výstupní funkce souborů.

Dobré zprávy a špatné zprávy

Všechny platformy podporované Xamarin.Forms podporou místního úložiště aplikace – úložiště, které je pro aplikaci soukromé.

Knihovny Xamarin.iOS a Xamarin.Android zahrnují verzi rozhraní .NET, kterou Xamarin výslovně přizpůsobila těmto dvěma platformám. Patří sem třídy, které System.IO můžete použít k provádění vstupně-výstupních operací se soubory s místním úložištěm aplikace na těchto dvou platformách.

Pokud ale tyto System.IO třídy vyhledáte v Xamarin.Forms PCL, nenajdete je. Problémem je, že Microsoft zcela přepracoval vstupně-výstupní operace souboru pro rozhraní API prostředí Windows Runtime. Programy cílené na Windows 8.1, Windows Phone 8.1 a Univerzální platforma Windows nepoužívají System.IO pro vstupně-výstupní operace souborů.

To znamená, že budete muset použít DependencyService (první probíranou v kapitole 9). Volání rozhraní API specifická pro platformu pro implementaci vstupně-výstupních operací souborů

Poznámka:

Knihovny přenosných tříd byly nahrazeny knihovnami .NET Standard 2.0 a .NET Standard 2.0 podporuje System.IO typy pro všechny Xamarin.Forms platformy. Pro většinu vstupně-výstupních úloh souborů už není nutné používat DependencyService . Další moderní přístup k vstupně-výstupním operacím souborů najdete v Xamarin.Forms tématu Zpracování souborů.

První snímek při vstupně-výstupních operacích souborů napříč platformami

Ukázka TextFileTryout definuje IFileHelper rozhraní pro vstupně-výstupní operace souboru a implementace tohoto rozhraní na všech platformách. Implementace prostředí Windows Runtime ale s metodami v tomto rozhraní nefungují, protože prostředí Windows Runtime vstupně-výstupní metody souboru jsou asynchronní.

Přizpůsobení vstupně-výstupních operací prostředí Windows Runtime souboru

Programy spuštěné v rámci prostředí Windows Runtime používají třídy v Windows.Storage oborech Windows.Storage.Streams názvů pro vstupně-výstupní operace souborů, včetně místního úložiště aplikace. Vzhledem k tomu, že Společnost Microsoft zjistila, že jakákoli operace vyžadující více než 50 milisekund by měla být asynchronní, aby nedošlo k blokování vlákna uživatelského rozhraní, jsou tyto vstupně-výstupní metody souborů většinou asynchronní.

Kód demonstrující tento nový přístup bude v knihovně, aby ho mohly používat jiné aplikace.

Knihovny specifické pro platformu

Je výhodné uložit opakovaně použitelný kód v knihovnách. To je samozřejmě obtížnější, když různé části opakovaně použitelného kódu jsou pro zcela různé operační systémy.

Řešení Xamarin.FormsBook.Platform ukazuje jeden přístup. Toto řešení obsahuje sedm různých projektů:

Všechny projekty jednotlivých platforem (s výjimkou Book.Platform.WinRT) mají odkazy na Xamarin.FormsBook.Platform.Xamarin.Forms Tři projekty Windows mají odkaz na Xamarin.FormsBook.Platform.WinRT.

Všechny projekty obsahují statickou Toolkit.Init metodu, která zajistí, že se knihovna načte, pokud na ni projekt v Xamarin.Forms řešení aplikace přímo neodkazuje.

Projekt Xamarin.FormsBook.Platform obsahuje nové IFileHelper rozhraní. Všechny metody teď mají názvy s příponami Async a návratové Task objekty.

Projekt Xamarin.FormsBook.Platform.WinRT obsahuje FileHelper třídu pro prostředí Windows Runtime.

Projekt Xamarin.FormsBook.Platform.iOS obsahuje FileHelper třídu pro iOS. Tyto metody teď musí být asynchronní. Některé metody používají asynchronní verze metod definovaných v StreamWriter : StreamReaderWriteAsync a ReadToEndAsync. Ostatní převedou výsledek na Task objekt pomocí FromResult metody.

Projekt Xamarin.FormsBook.Platform.Android obsahuje podobnou FileHelper třídu pro Android.

Projekt Xamarin.FormsBook.Platform obsahuje FileHelper také třídu, která usnadňuje použití objektu DependencyService .

Aby bylo možné tyto knihovny používat, musí řešení aplikace obsahovat všechny projekty v Xamarin.Formsřešení Book.Platform a každý z projektů aplikace musí mít odkaz na odpovídající knihovnu v Xamarin.FormsBook.Platform.

Řešení TextFileAsync ukazuje, jak používat Xamarin.Formsknihovny Book.Platform . Každý z projektů má volání Toolkit.Init. Aplikace využívá asynchronní vstupně-výstupní funkce souborů.

Zachování na pozadí

Metody v knihovnách, které provádějí volání více asynchronních metod , jako WriteFileAsync ReadFileASync jsou metody ve třídě prostředí Windows Runtime FileHelper , mohou být poněkud efektivnější pomocí ConfigureAwait metody, aby se zabránilo přepnutí zpět do vlákna uživatelského rozhraní.

Nezablokujte vlákno uživatelského rozhraní!

Někdy je lákavé vyhnout se použití ContinueWith nebo await použití Result vlastnosti v metodách. Tomu by se mělo vyhnout, protože může blokovat vlákno uživatelského rozhraní nebo dokonce zablokovat aplikaci.

Vaše vlastní očekávané metody

Určitý kód můžete spustit asynchronně tak, že ho předáte jedné z Task.Run metod. Můžete volat Task.Run v asynchronní metodě, která zpracovává některé režijní náklady.

Task.Run Různé vzory jsou popsány níže.

Základní sada Mandelbrot

Chcete-li nakreslit Mandelbrot v reálném čase, Xamarin.Forms Knihovna toolkit má strukturu podobnou Complex té v System.Numerics oboru názvů.

Ukázka MandelbrotSet má v souboru kódu metodu CalculateMandeblotAsync , která vypočítá základní černobílou sadu Mandelbrot a používá BmpMaker ji k jeho vložení na rastrový obrázek.

Označení průběhu

Pokud chcete hlásit průběh z asynchronní metody, můžete vytvořit instanci Progress<T> třídy a definovat asynchronní metodu tak, aby měla argument typu IProgress<T>. To je ukázáno ve vzorku MandelbrotProgress.

Zrušení úlohy

Můžete také napsat asynchronní metodu, která se dá zrušit. Začínáte třídou s názvem CancellationTokenSource. Vlastnost Token je hodnota typu CancellationToken. Tato funkce se předá asynchronní funkci. Program volá metodu Cancel CancellationTokenSource (obecně v reakci na akci uživatelem) pro zrušení asynchronní funkce.

Asynchronní metoda může pravidelně kontrolovat IsCancellationRequested vlastnost CancellationToken a ukončit, pokud je truevlastnost , nebo jednoduše volat metoduThrowIfCancellationRequested, v takovém případě metoda končí .OperationCancelledException

Ukázka MandelbrotCancellation demonstruje použití zrušené funkce.

An MVVM Mandelbrot

Ukázka MandelbrotXF má rozsáhlejší uživatelské rozhraní a je většinou založená na třídách MandelbrotModel MandelbrotViewModel :

Triple screenshot of Mandelbrot X F

Zpět na web

Třída WebRequest použitá v některých ukázkách používá starý asynchronní protokol s názvem Asynchronní programovací model nebo APM. Takovou třídu můžete převést na moderní protokol TAP pomocí jedné z FromAsync metod ve TaskFactory třídě. Ukázka ApmToTap to ukazuje.