23
Yu Zhaohui http://yuyijq.cnblogs.com .NET 平平平平平平平平

Async programming on NET

  • Upload
    yuyijq

  • View
    984

  • Download
    1

Embed Size (px)

DESCRIPTION

.NET平台上的异步编程风格的变化,从传统的异步编程,到利用第三方类库以及新出现的F#异步工作流,还有未来.NET 5.0中的TAP

Citation preview

Page 1: Async programming on NET

Yu Zhaohui

http://yuyijq.cnblogs.com

.NET平台上的异步编程

Page 2: Async programming on NET

• 余昭辉,网名横刀天笑• http://yuyijq.cnblogs.com

• Programming language fans

• Design Pattern & Architecture

• .NET CLR

• C# MVP

Page 3: Async programming on NET

90%以上的应用都是在以错误的方式使用线程 - Jeffrey Richter

Page 4: Async programming on NET
Page 5: Async programming on NET
Page 6: Async programming on NET

Write async program is hard, and write stable program is even harder.

Page 7: Async programming on NET

private void btnDownload_Click(object sender, EventArgs e){

try{var request = HttpWebRequest.Create(“http://yuyijq.cnblogs.com”);var response = request.GetResponse();using(var stream = response.GetResponseStream()){

return stream.ReadToEnd();}

}catch{//…}}

Page 8: Async programming on NET
Page 9: Async programming on NET

var request = HttpWebRequest.Create(“http://yuyijq.cnblogs.com”);request.BeginGetResponse(DownloadCompeleted,request);

public void DownloadCompeleted(IAsyncResult ar){

var request = (HttpWebRequest)ar.AsyncState;var response = request.EndGetResponse();var stream = response.GetResponseStream();ReadHelper(stream);

}public void ReadHelper(Stream stream){

byte[] buffer = new byte[1024];stream.BeginRead(buffer,0,1024,(ar) =>{

var actualRead = stream.EndRead();if(actualRead == 0){

stream.Close();}else{

//proccess dataReadHelper(stream);

}},null);

}

Page 10: Async programming on NET

传统异步的异步编程

• For, while 等基本构造无法使用• Try catch无法使用,异常处理非常困难• Using无法使用,代码变糟• 所有异步方法分为二段式:发起请求和请求结束处理。代码进一步腐化

这样造成的结果是:放弃效率更高的异步方式,采用效率低的同步方式

Page 11: Async programming on NET

其实我们要寻找的是一种获得 continue的方式:

Continution Passing Style

Page 12: Async programming on NET

Print(Add(5,6))

void Print(int result){ Console.WriteLine(result);}int Add(int l, int r){

return l + r;}

Add(5, 6, (ret) => Print(ret));

void Add(int l, int r, Action<int> continue){

continue(l + r);}

Page 13: Async programming on NET

神奇的 yield

Private IEnumerator<int> Caclute(){

int i = 5 + 6;yield return 1;Console.WriteLine(i);i = 4 * 5;yield return 1;Console.WriteLine(i);//…

}

Private Ienumerator<int> Caclute(){

return new StateMachine();}

Public class StateMachine{ public bool MoveNext() {

switch(state){ case 0: //…}

}}

While(Caclute().MoveNext()){//…

}

Page 14: Async programming on NET

如是我们可以这样编写异步代码:Private Ienumerator<int> Download(){

var req = HttpWebRequest.Create(“http://yuyijq.cnblogs.com”);var ar1 = req.BeginGetResponse(__?__,null);yield return 1;var resp = req.EndGetResponse(ar1);using(var stream = resp.GetResponseStream()){

byte[] buffer = new byte[1024];do{ var ar2 =stream.BeginRead(buffer,0,1024,__?__,null); yield return 1; var actualRead = stream.EndRead(ar2);}while(actualRead != 0)

}}

self.MoveNext

self.MoveNext

Page 15: Async programming on NET

AsyncRunner runner = new AsyncRunner();Runner.Run(Download(runner));

Public void Run(Ienumerator<int> async){

this.async = async;async.MoveNext();

}

Public AsyncCallback Continue(){

return (ar) => this.async.MoveNext();}

Page 16: Async programming on NET

Private Ienumerator<int> Download(AsyncRunner runner){

var req = HttpWebRequest.Create(“http://yuyijq.cnblogs.com”);var ar1 = req.BeginGetResponse(runner.Continue,null);yield return 1;var resp = req.EndGetResponse(ar1);using(var stream = resp.GetResponseStream()){

byte[] buffer = new byte[1024];do{ var ar2 =stream.BeginRead(buffer,0,1024,runner.Continue,null); yield return 1; var actualRead = stream.EndRead(ar2);}while(actualRead != 0)

}}

Page 17: Async programming on NET

第三方类库支持

• Jeffrey Ritcher 的 AsyncEnumerator

• CCR 的 Iterator

• Rx(reactive programming)

Page 18: Async programming on NET

F#简介• 由微软剑桥研究院的 Don Syme开发• 静态的,强类型的,基于 .NET平台的函数式编程语言• 历史基于和 .NET一样长• 起源于 Ocame

Page 19: Async programming on NET

F# ASYNC WORKFLOW

def download url = async{ let req = WebRequest.Create(url) let! resp = req.AsyncGetResponse() use stream = resp.GetResponseStream() use reader = new StreamReader(stream) let! content = reader.AsyncReadToEnd() return content }

builder.Delay( var req = WebRequest.Create(url); builder.Bind(req.AsyncGetReponse(),(resp) =>{ builder.Using(resp.GetResponseStream(),(stream) =>{ builder.Using(new StreamReader(stream),(reader) =>{ builder.Bind(reader.AsyncReadToEnd(),(content) =>{ builder.Return(content); }) }) }) }) );

Page 20: Async programming on NET

F# WORKFLOW

type Async<‘T>

type AsyncBuilder with member Return : ‘T -> Async<‘T> member Delay : (unit -> Async<‘T>) -> Async<‘T> member Using : ‘T * (‘T -> Async<‘U>) -> Async<‘U> when ‘T :> System.Idisposable member Bind : Async<‘T> * (‘T -> Async<‘U>) -> Async<‘U>

let async = new AsyncBuilder

async{ let!...}

Page 21: Async programming on NET

.NET 5.0 TAP

Public async String Download(String url){ var req = WebRequest.Create(url); var resp = await req.GetResponseAsync(); using(var stream = resp.GetResponseStream()) { }}

Page 22: Async programming on NET

Asynchrony doesn't mean "background thread”

Lucian Wischik

Page 23: Async programming on NET

Thank you