Krótka historia asynchroniczności w .NET 1-4.5

62
Krótka historia asynchroniczności w .NET 1-4.5 Jakub Binkowski

description

Krótka historia asynchroniczności w .NET 1-4.5. Jakub Binkowski. O mnie. Jakub Binkowski Senior .NET Developer @ Rule Financial Microsoft MVP w latach 2008-2011 MCP, MCTS, MCPD Lider Łódzkiej Grupy Profesjonalistów IT & .NET [email protected]. Agenda. Dlaczego asynchroniczność? - PowerPoint PPT Presentation

Transcript of Krótka historia asynchroniczności w .NET 1-4.5

Page 1: Krótka historia asynchroniczności  w .NET 1-4.5

Krótka historiaasynchroniczności w .NET 1-4.5

Jakub Binkowski

Page 2: Krótka historia asynchroniczności  w .NET 1-4.5

O mnie Jakub Binkowski Senior .NET Developer @ Rule Financial

Microsoft MVP w latach 2008-2011 MCP, MCTS, MCPD

Lider Łódzkiej Grupy Profesjonalistów IT & .NET

[email protected]

Page 3: Krótka historia asynchroniczności  w .NET 1-4.5

Agenda Dlaczego asynchroniczność? Jak?

Asynchronous Programming Model (APM) Event-based Asynchronous Pattern (EAP) Task-based Asynchronous Pattern (TAP) Async i await w .NET 4.5

Asynchroniczny ASP.NET Testy jednostkowe

Page 4: Krótka historia asynchroniczności  w .NET 1-4.5

Dlaczego asynchroniczność?

Page 5: Krótka historia asynchroniczności  w .NET 1-4.5

Przypomnienie: Wątek jest drogi Pamięć:

ponad 1MB (pamięć zarezerwowana)

Czas: Powiadomienia o utworzeniu i zamknięciu wątku

(do wszystkich DLL) Przełączenia kontekstu

Page 6: Krótka historia asynchroniczności  w .NET 1-4.5

Przypomnienie: Pula wątków Zbiór wątków dostępnych dla aplikacji Jedna na proces (CLR)

Ilość wątków w puli Minimalna ilość wątków = ilość procesorów

logicznych Maksymalna – zależy od środowiska Algorytm – czarna skrzynka

Klasa ThreadPool

Page 7: Krótka historia asynchroniczności  w .NET 1-4.5

Przykład 1 – ASP.NET

Page 8: Krótka historia asynchroniczności  w .NET 1-4.5

Przykład 1 – ASP.NETpublic ActionResult AvatarDetails(){    var url = "http://...";    var data = new WebClient().DownloadData(url);

    var bitmap = new Bitmap(new MemoryStream(data));    var model = new AvatarModel    {        AvatarUrl = url,        Size = data.Length,        Width = bitmap.Width,        Height = bitmap.Height    };

    return View(model);}

Page 9: Krótka historia asynchroniczności  w .NET 1-4.5

Gdzie jest problem? Pula wątków obsługujących żądania Dla uproszczenia – pula = 3 wątki; 3 procesory

HTMLDBWeb Servi

ceHTML HTML

CPU = 66%

Web Servi

ce

Page 10: Krótka historia asynchroniczności  w .NET 1-4.5

Gdzie jest problem? Pula wątków obsługujących żądania Dla uproszczenia – pula = 3 wątki; 3 procesory

HTML HTMLDBWeb Servi

ce

CPU = 33%

Web Servi

ceHTML

Page 11: Krótka historia asynchroniczności  w .NET 1-4.5

Gdzie jest problem? Pula wątków obsługujących żądania Dla uproszczenia – pula = 3 wątki; 3 procesory

HTML HTML DBWeb Servi

ce

CPU = 0%

Web Servi

ceHTML

!

Page 12: Krótka historia asynchroniczności  w .NET 1-4.5

Operacje obliczeniowe

Wątek

Page 13: Krótka historia asynchroniczności  w .NET 1-4.5

Operacje I/O (synchroniczne)

Operacja I/O

Wątek

Urządzenie

Page 14: Krótka historia asynchroniczności  w .NET 1-4.5

Gdyby… 1 cykl procesora = 1 sekunda:

Rejestr: 1s Pamięć: 5-10s Dysk: 3 miesiące Sieć: 30 lat

Page 15: Krótka historia asynchroniczności  w .NET 1-4.5

Przykład 2 - WPF

Page 16: Krótka historia asynchroniczności  w .NET 1-4.5

Przykład 2 - WPFvoid Button_Click(object sender, RoutedEventArgs e){    var data = new WebClient().DownloadData(tbUrl.Text);

    var bitmap = new BitmapImage();    bitmap.BeginInit();    bitmap.StreamSource = new MemoryStream(data);    bitmap.EndInit();

    imgAvatar.Source = bitmap;} Uwaga!

Brzydki kod

Page 17: Krótka historia asynchroniczności  w .NET 1-4.5

Przykład 2 – WPF (aplikacja desktop) Tylko jeden wątek obsługuje UI W czasie wykonywania operacji aplikacja nie

odpowiada

Page 18: Krótka historia asynchroniczności  w .NET 1-4.5

Programowanie synchroniczneProblemy Problem 1:

Pula wątków blokowana przez zewnętrzne urządzenia (I/O)

Problem 2:Wątek UI zajęty przez długotrwałą operację

Page 19: Krótka historia asynchroniczności  w .NET 1-4.5

Wzorce asynchroniczne

APM vs EAP vs TAP

Page 20: Krótka historia asynchroniczności  w .NET 1-4.5

Kod synchroniczny API:public interface IMyType{ int DoSomething(int a);}

Wywołanie:IMyType type = /*..*/;int result = type.DoSomething(10);

Page 21: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchronous Programming ModelAPI

public interface IMyType{ IAsyncResult BeginDoSomething(int a, AsyncCallback callback, object state); int EndDoSomething(IAsyncResult asyncResult);}

Page 22: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchronous Programming Model Użycie – wariant 1

IMyType type = /*..*/;IAsyncResult asyncRes = type.BeginDoSomething(10, null, null);//...int result = type.EndDoSomething(asyncRes);//...

Page 23: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchronous Programming ModelUżycie – wariant 2class MyProgram{ private IMyType _type;

public void Begin() { _type.BeginDoSomething(10, OnDoSomethingFinished, null); }

private void OnDoSomethingFinished(IAsyncResult asyncRes) { int result = _type.EndDoSomething(asyncRes); //... }}

Page 24: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchronous Programming ModelUżycie – wariant 2b

IMyType type = /*..*/;type.BeginDoSomething(10, asyncRes => { int result = type.EndDoSomething(asyncRes); //... }, null);

Page 25: Krótka historia asynchroniczności  w .NET 1-4.5

DemoAsynchronous Programming Model

Page 26: Krótka historia asynchroniczności  w .NET 1-4.5

Trochę historii Oryginalnie IAsyncResult jedynym wzorcem Wg zespołu Windows Forms IAsyncResult jest

zbyt skomplikowany nie pasuje do trybu design wymaga pilnowania wątków

Efekt – alternatywne podejście:Event-base Asynchronous Programming

Page 27: Krótka historia asynchroniczności  w .NET 1-4.5

Event-based Asynchronous ProgrammingAPIpublic interface IMyType{ void DoSomethingAsync(int a); event DoSomethingCompletedEventHandler DoSomethingCompleted;}

public class DoSomethingCompletedEventArgs: AsyncCompletedEventArgs{ public int Result { get; set; } /*…*/}

public delegate void DoSomethingCompletedEventHandler( object sender, DoSomethingCompletedEventArgs args);

Page 28: Krótka historia asynchroniczności  w .NET 1-4.5

Event-based Asynchronous ProgrammingUżycie

IMyType type = /*...*/;type.DoSomethingCompleted += (sender, args) => { int result = args.Result; //... };type.DoSomethingAsync(10);

Page 29: Krótka historia asynchroniczności  w .NET 1-4.5

DemoEvent-based Asynchronous Programming

Page 30: Krótka historia asynchroniczności  w .NET 1-4.5

APMZastosowanie FCL: 60 klas

Strumienie (System.IO.Stream) DNS (System.Net.Dns) Gniazda sieciowe

(System.Net.Sockets.Socket) Żądania sieciowe (System.Net.WebRequest) Polecenia SQL

(System.Data.SqlClient.SqlCommand) Porty (System.IO.Ports.SerialPort) Web/Service References

Page 31: Krótka historia asynchroniczności  w .NET 1-4.5

EAPZastosowanie FCL: 17 klas

System.ComponentModel.BackgroundWorker; System.Net.WebClient; System.Net.NetworkInformation.Ping; System.Windows.Forms.PictureBox; System.Net.Mail.SmtpClient; i inne…

Page 32: Krótka historia asynchroniczności  w .NET 1-4.5

APM czy EAP?

Page 33: Krótka historia asynchroniczności  w .NET 1-4.5

Gdzie jest problem?

Page 34: Krótka historia asynchroniczności  w .NET 1-4.5

Gdzie jest problem?

Page 35: Krótka historia asynchroniczności  w .NET 1-4.5

W drodze ku lepszemu .NET 4.0 wprowadził nowy model

programowania równoległego – Task Parallel Library

C# 4.5 wprowadzi nowy model programowania asynchronicznego:Task-based Asynchronous Programming

APM i EAP staną się przestarzałe

Page 36: Krótka historia asynchroniczności  w .NET 1-4.5

Idea TAP Niech deweloperzy piszą kod

prawie tak samo „Magią” niech zajmie się kompilator

Page 37: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingAPI

public interface IMyType{ Task<int> DoSomethingTask(int a);}

Page 38: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingAPI

public interface IMyType{ Task<int> DoSomethingTask(int a);}

Page 39: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingUżycie

public async Task<bool> IsSomethingZeroAsync(int a){ IMyType type = /*...*/; var value = await type.DoSomethingAsync(a); return value == 0;}

Page 40: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingUżycie

public async Task<bool> IsSomethingZeroAsync(int a){ IMyType type = /*...*/; var value = await type.DoSomethingAsync(a); return value == 0;}

Page 41: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingUżycie

public async Task<bool> IsSomethingZeroAsync(int a){ IMyType type = /*...*/; var value = await type.DoSomethingAsync(a); return value == 0;}

Page 42: Krótka historia asynchroniczności  w .NET 1-4.5

Task-based Asynchronous ProgrammingUżycie

public async Task<bool> IsSomethingZeroAsync(int a){ IMyType type = /*...*/; var value = await type.DoSomethingAsync(a); return value == 0;}

Page 43: Krótka historia asynchroniczności  w .NET 1-4.5

DemoTask-based Asynchronous Programming

Page 44: Krótka historia asynchroniczności  w .NET 1-4.5

ASP.NET

Asynchroniczne ASP.NET MVC 3 i 4

Page 45: Krótka historia asynchroniczności  w .NET 1-4.5

DemoASP.NET MVC 3

Page 46: Krótka historia asynchroniczności  w .NET 1-4.5

Synchroniczny kontrolerASP.NET MVC 3public class HomeController : Controller{    public ActionResult AvatarDetails()    {        var client = new WebClient();        var data = client.DownloadData(new Uri("…"));        //...        return View();    }}

Page 47: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 3public class HomeController : AsyncController{    public void AvatarDetailsAsync()    {        AsyncManager.OutstandingOperations.Increment();        var client = new WebClient();        client.DownloadDataCompleted += (s, a) =>            {                AsyncManager.Parameters["data"] = a.Result;                AsyncManager.OutstandingOperations.Decrement();            };        client.DownloadDataAsync(new Uri("…"));    }     public ActionResult AvatarDetailsCompleted(byte[] data)    {        //...        return View();    }}

Page 48: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 3public class HomeController : AsyncController{    public void AvatarDetailsAsync()    {        AsyncManager.OutstandingOperations.Increment();        var client = new WebClient();        client.DownloadDataCompleted += (s, a) =>            {                AsyncManager.Parameters["data"] = a.Result;                AsyncManager.OutstandingOperations.Decrement();            };        client.DownloadDataAsync(new Uri("…"));    }     public ActionResult AvatarDetailsCompleted(byte[] data)    {        //...        return View();    }}

Page 49: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 3public class HomeController : AsyncController{    public void AvatarDetailsAsync()    {        AsyncManager.OutstandingOperations.Increment();        var client = new WebClient();        client.DownloadDataCompleted += (s, a) =>            {                AsyncManager.Parameters["data"] = a.Result;                AsyncManager.OutstandingOperations.Decrement();            };        client.DownloadDataAsync(new Uri("…"));    }     public ActionResult AvatarDetailsCompleted(byte[] data)    {        //...        return View();    }}

Page 50: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 3public class HomeController : AsyncController{    public void AvatarDetailsAsync()    {        AsyncManager.OutstandingOperations.Increment();        var client = new WebClient();        client.DownloadDataCompleted += (s, a) =>            {                AsyncManager.Parameters["data"] = a.Result;                AsyncManager.OutstandingOperations.Decrement();            };        client.DownloadDataAsync(new Uri("…"));    }     public ActionResult AvatarDetailsCompleted(byte[] data)    {        //...        return View();    }}

Page 51: Krótka historia asynchroniczności  w .NET 1-4.5

DemoASP.NET MVC 4 + async

Page 52: Krótka historia asynchroniczności  w .NET 1-4.5

Synchroniczny kontrolerASP.NET MVC 4public class HomeController : Controller{    public ActionResult AvatarDetails()    {        var client = new WebClient();        var data = client.DownloadData(new Uri("…"));        //...        return View();    }}

Page 53: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 4public class HomeController : AsyncController{    public async Task<ActionResult> AvatarDetails()    {        var client = new WebClient();        var data = await client.DownloadDataTaskAsync(new Uri("…"));        //...        return View();    }}

Page 54: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 4public class HomeController : AsyncController{    public async Task<ActionResult> AvatarDetails()    {        var client = new WebClient();        var data = await client.DownloadDataTaskAsync(new Uri("…"));        //...        return View();    }}

Page 55: Krótka historia asynchroniczności  w .NET 1-4.5

Asynchroniczny kontrolerASP.NET MVC 4public class HomeController : AsyncController{    public async Task<ActionResult> AvatarDetails()    {        var client = new WebClient();        var data = await client.DownloadDataTaskAsync(new Uri("…"));        //...        return View();    }}

Page 56: Krótka historia asynchroniczności  w .NET 1-4.5

„async” a testy jednostkowe

Page 57: Krótka historia asynchroniczności  w .NET 1-4.5

DemoSynchronous unit tests

Page 58: Krótka historia asynchroniczności  w .NET 1-4.5

DemoAsynchronous unit tests

Page 59: Krótka historia asynchroniczności  w .NET 1-4.5

Podsumowanie 3 wzorce programowania asynchronicznego:

APM (Asynchronous Programming Model) EAP (Event-based Asynchronous Programming) TAP (Task-based Asynchronous Programming)

TAP zastępuje APM i EAP nowe metody w całym .NET Framework wsparcie w ASP.NET wsparcie w WCF

Potężne wsparcie kompilatora – async i await

Page 62: Krótka historia asynchroniczności  w .NET 1-4.5

Dziękuję za uwagę. Pytania?