550 likes | 702 Views
Asynchroniczność w Windows 8. Jakub Binkowski. O mnie. Jakub Binkowski. 2008 - 2011. Lead .NET Developer. Agenda. Dlaczego asynchronicz-ność ?. Historia: APM, EAP. async i await. ASP.NET MVC. Windows 8 Runtime. Internals i architektura. Dlaczego asynchroniczność?.
E N D
Asynchroniczność w Windows 8 Jakub Binkowski
O mnie Jakub Binkowski 2008 - 2011 Lead .NET Developer
Agenda Dlaczego asynchronicz-ność? Historia: APM, EAP async i await ASP.NET MVC Windows 8 Runtime Internalsi architektura
Przykładowa metoda… publicvoidDownloadImageAsPng(stringurl, stringfileName) { varwebclient = newWebClient(); varimageBytes = webclient.DownloadData(url); using(varimageStream = newMemoryStream(imageBytes)) { var bitmap = Bitmap.FromStream(imageStream); bitmap.Save(fileName, ImageFormat.Png); } } Pobranie z sieci Zapis na dysk
Ile to trwa? • Gdyby 1 cykl procesora = 1 sekunda: • Rejestr: 1s • Pamięć: 5-10s • Dysk: 3 miesiące • Sieć: 30 lat
Operacje obliczeniowe Wątek
Operacje I/O synchroniczne Wątek Urządzenie Operacja I/O
Problemy • Różne problemy w różnych środowiskach: • Aplikacje desktop (Metro, WPF, …) • Aplikacje serwerowe (ASP.NET, WCF, …)
Aplikacje desktop • Jest jeden wątek UI • Gdy jest zajęty aplikacja przestaje odpowiadać
Aplikacje serwerowe • Oparte o pulę wątków • Gdy wszystkie wątki z puli są zajęte – żądania się kolejkują • Pula wątków rośnie, ale: • Każdy wątek to 1MB zarezerwowanej pamięci
Przykład – aplikacja ASP.NET • Dla uproszczenia: • 3 procesory • 3 wątki w puli • 2 rodzaje operacji: • Tylko HTML – szybka operacja w pamięci • Dostęp do zewnętrznych zasobów (DB, Web Service) - wole
Przykład – aplikacja ASP.NET Żądania aktualnie obsługiwane Kolejka żądań oczekujących HTML Web Service HTML DB HTML DB HTML CPU = 66%
Przykład – aplikacja ASP.NET HTML Web Service DB HTML HTML DB CPU = 33%
Przykład – aplikacja ASP.NET Żądania, które można by obsłużyć… Web Service DB HTML HTML DB CPU = 0%
Problemy operacji synchronicznych • Desktop „zawieszenie się” • Server spadek wydajności • Rozwiązanie – operacje asynchroniczne
Operacje I/O asynchroniczne Wątek 1 Urządzenie Operacja I/O Wątek 2
Asynchroniczność w .NET 1.1 • Asynchronous Programming Model Demo
Asynchronous Programming Model • Wg zespołu Windows FormsAPM jest: • zbyt skomplikowany • nie pasuje do trybu design • wymaga pilnowania wątków
Asynchroniczność w .NET 2.0 • Event-baseAsynchronous Programming Demo
Problem APM i EAP… publicvoidDownloadFile(stringurl) { try { varwebClient = newWebClient(); var data = webClient.DownloadData(url); //carry on... } catch (Exception ex) { //handle error... } }
Problem APM i EAP… publicvoidDownloadFile(stringurl) { try { varwebClient = newWebClient(); webClient.DownloadDataCompleted += DownloadFileCompleted; webClient.DownloadDataAsync(newUri(url)); } catch (Exception ex) { //handle error } } privatevoidDownloadFileCompleted(objectsender, DownloadDataCompletedEventArgs e) { if (e.Error == null) { var data = e.Result; //carry on... } else { //handle error } }
A gdyby można było… • Napisać taki kod jak synchroniczny • Niech kompilator zajmie się asynchronicznością • Niech debugger działa jak gdyby kod był synchroniczny
async! publicasyncvoidDownloadFile(stringurl) { try { varwebClient = newWebClient(); var data = awaitwebClient.DownloadDataTaskAsync( newUri(url)); //carry on... } catch (Exception ex) { //handle error... } }
Jak działa async? publicasyncTaskDownloadFile(stringurl) { varwc = newWebClient(); var data = awaitwc.DownloadDataTaskAsync(/*...*/); //carry on... }
async Demo
Co zrobi kompilator? publicTaskDownloadFile(stringurl) { varwc = newWebClient(); vardownloadTask = wc.DownloadDataTaskAsync(/*...*/); varcontinuationTask = downloadTask.ContinueWith(t => { if (t.Exception != null) throwt.Exception.InnerException; //carry on... }); returncontinuationTask; } Uwaga! Bardzo duże uproszczenie.
Metody async publicasyncvoidFireAndForget() { /*...*/ } publicasyncTaskFireAndRemember() { /*...*/ } publicasyncTask<int> FireAndReturn() { /*...*/ return 1; }
asyncTask vs asyncvoid asyncTaskXxx() asyncvoidXxx() • „Fire and forget” • Przeznaczenie: • Event handlery • Kompatybilność wstecz • Można poczekać na zakończenie wykonania (i sprawdzić np. exception)
Anonimowy async? Czemu nie! Func<Task<int>> fireAndReturn = async ()=> { /**/ return 1; };
ASP.NET MVC 3 – kontroler publicclassHomeController : Controller{ publicActionResultDownload() {varclient = newWebClient(); vardata = client.DownloadData(newUri("…"));//...return View(); }} Potencjalnie długotrwała operacja
ASP.NET MVC 3 – kontroler asynchroniczny publicclassHomeController : AsyncController{ publicvoidDownloadAsync() {AsyncManager.OutstandingOperations.Increment();var client = newWebClient();client.DownloadDataCompleted += (s, a) => {AsyncManager.Parameters["data"] = a.Result;AsyncManager.OutstandingOperations.Decrement(); };client.DownloadDataAsync(newUri("…")); }publicActionResultAvatarDetailsCompleted(byte[] data) {//...return View(); }}
ASP.NET MVC 3 • Demo Kontroler synchroniczny Kontroler asynchroniczny
ASP.NET MVC 4 – kontroler synchroniczny(przypomnienie) publicclassHomeController : Controller{ publicActionResultDownload() {varclient = newWebClient(); vardata = client.DownloadData(newUri("…"));//...return View(); }}
ASP.NET MVC 4 – kontroler asynchroniczny publicclassHomeController : AsyncController{ publicasyncTask<ActionResult>Download() {varclient = newWebClient(); vardata = awaitclient.DownloadDataTaskAsync(/*…*/);//...return View(); }}
ASP.NET MVC 4 • Demo Kontroler asynchroniczny
Async w Windows Runtime User Interface HTML5 / CSS XAML DirectX Controls Data Binding SVG Tiles Input Accessibility Printing Communications & Data Devices Geolocation NFC Printer Contracts XML Web Sensors Portable Devices Streams Networking Notifications Media AtomPub Local & Cloud Storage Capture Visual Effects SMS Background Transfer Transcoding PlayTo Fundamentals App Lifetime Authentication Cryptography Globalization .NET Win32
IAsync* a Task IAsyncAction Task IAsyncOperation<TResult> Task<TResult>
Pytanie Czy skoro można wywołać na: • Task • IAsyncAction/Operation to czy można wywołać na czymś jeszcze innym?
await – na czym można „czekać”? var my = newMyClass(); await my; publicclassMyClass { publicMyAwaiterGetAwaiter() { /*..*/} } publicclassMyAwaiter : INotifyCompletion { publicboolIsCompleted { get{/*...*/} } publicvoidGetResult() {/*..*/} publicvoidOnCompleted(Actioncontinuation) {/*..*/} } Może też być extensionmethod
Co będzie w zmiennej type? vartask = Task.Run<int>( newFunc<int>(() => { thrownewException(); })); try { awaittask; } catch(Exception ex) { stringtype = ex.GetType().Name; } vartask = Task.Run<int>( newFunc<int>(() => { thrownewException(); })); task.ContinueWith(t => { try { var res = t.Result; } catch (Exception ex) { stringtype = ex.GetType().Name; } });
await a Exception Demo