精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C# 5.0新特性:Async和Await使異步編程更簡單

開發(fā) 后端
在之前的C#基礎(chǔ)知識系列文章中只介紹了從C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,對于C#又有了新特性的增加——就是C#5.0中async和await兩個關(guān)鍵字,這兩個關(guān)鍵字簡化了異步編程,之所以簡化了,還是因為編譯器給我們做了更多的工作,下面就具體看看編譯器到底在背后幫我們做了哪些復(fù)雜的工作的。

一、引言

在之前的C#基礎(chǔ)知識系列文章中只介紹了從C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,對于C#又有了新特性的增加——就是C#5.0中async和await兩個關(guān)鍵字,這兩個關(guān)鍵字簡化了異步編程,之所以簡化了,還是因為編譯器給我們做了更多的工作,下面就具體看看編譯器到底在背后幫我們做了哪些復(fù)雜的工作的。

二、同步代碼存在的問題

對于同步的代碼,大家肯定都不陌生,因為我們平常寫的代碼大部分都是同步的,然而同步代碼卻存在一個很嚴重的問題,例如我們向一個Web服務(wù)器發(fā)出一個請求時,如果我們發(fā)出請求的代碼是同步實現(xiàn)的話,這時候我們的應(yīng)用程序就會處于等待狀態(tài),直到收回一個響應(yīng)信息為止,然而在這個等待的狀態(tài),對于用戶不能操作任何的UI界面以及也沒有任何的消息,如果我們試圖去操作界面時,此時我們就會看到"應(yīng)用程序為響應(yīng)"的信息(在應(yīng)用程序的窗口旁),相信大家在平常使用桌面軟件或者訪問web的時候,肯定都遇到過這樣類似的情況的,對于這個,大家肯定會覺得看上去非常不舒服。引起這個原因正是因為代碼的實現(xiàn)是同步實現(xiàn)的,所以在沒有得到一個響應(yīng)消息之前,界面就成了一個"卡死"狀態(tài)了,所以這對于用戶來說肯定是不可接受的,因為如果我要從服務(wù)器上下載一個很大的文件時,此時我們甚至不能對窗體進行關(guān)閉的操作的。為了具體說明同步代碼存在的問題(造成界面開始),下面通過一個程序讓大家更形象地看下問題所在:

  1. // 單擊事件  
  2.         private void btnClick_Click(object sender, EventArgs e)  
  3.         {  
  4.             this.btnClick.Enabled = false;  
  5.  
  6.             long length = AccessWeb();  
  7.             this.btnClick.Enabled = true;  
  8.             // 這里可以做一些不依賴回復(fù)的操作  
  9.             OtherWork();  
  10.  
  11.             this.richTextBox1.Text += String.Format("\n 回復(fù)的字節(jié)長度為:  {0}.\r\n", length);  
  12.             txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();  
  13.         }  
  14.  
  15.         private  long AccessWeb()  
  16.         {  
  17.             MemoryStream content = new MemoryStream();  
  18.  
  19.             // 對MSDN發(fā)起一個Web請求  
  20.             HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/"as HttpWebRequest;  
  21.             if (webRequest != null)  
  22.             {  
  23.                 // 返回回復(fù)結(jié)果  
  24.                 using (WebResponse response = webRequest.GetResponse())  
  25.                 {  
  26.                     using (Stream responseStream = response.GetResponseStream())  
  27.                     {  
  28.                         responseStream.CopyTo(content);  
  29.                     }  
  30.                 }  
  31.             }  
  32.  
  33.             txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString();  
  34.             return content.Length;  
  35.         } 

運行程序后,當我們點擊窗體的 "點擊我"按鈕之后,在得到服務(wù)器響應(yīng)之前,我們不能對窗體進行任何的操作,包括移動窗體,關(guān)閉窗體等,具體運行結(jié)果如下:

三、傳統(tǒng)的異步編程來改善程序的響應(yīng)

 上面部分我們已經(jīng)看到同步方法所帶來的實際問題了,為了解決類似的問題,.NET Framework很早就提供了對異步編程的支持,下面就用.NET 1.0中提出的異步編程模型(APM)來解決上面的問題,具體代碼如下(注釋的部分通過獲得GUI線程的同步上文對象,然后同步調(diào)用同步上下文對象的post方法把要調(diào)用的方法交給GUI線程去處理,因為控件本來就是由GUI線程創(chuàng)建的,然后由它自己執(zhí)行訪問控件的操作就不存在跨線程的問題了,程序中使用的是調(diào)用RichTextBox控件的Invoke方式來異步回調(diào)訪問控件的方法,其實背后的原來和注釋部分是一樣的,調(diào)用RichTextBox控件的Invoke方法可以獲得創(chuàng)建RichTextBox控件的線程信息(也就是前一種方式的同步上下文),然后讓Invoke回調(diào)的方法在該線程上運行):

  1. private void btnClick_Click(object sender, EventArgs e)  
  2.         {  
  3.             this.richTextBox1.Clear();  
  4.             btnClick.Enabled = false;  
  5.             AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod);  
  6.             IAsyncResult result = caller.BeginInvoke(GetResult, null);  
  7.  
  8.             //// 捕捉調(diào)用線程的同步上下文派生對象  
  9.             //sc= SynchronizationContext.Current;  
  10.         }  
  11.      
  12.         # region 使用APM實現(xiàn)異步編程  
  13.         // 同步方法  
  14.         private string TestMethod()  
  15.         {         
  16.             // 模擬做一些耗時的操作  
  17.             // 實際項目中可能是讀取一個大文件或者從遠程服務(wù)器中獲取數(shù)據(jù)等。  
  18.             for (int i = 0; i < 10; i++)  
  19.             {  
  20.                 Thread.Sleep(200);  
  21.             }  
  22.  
  23.             return "點擊我按鈕事件完成";  
  24.         }  
  25.          
  26.         // 回調(diào)方法  
  27.         private void GetResult(IAsyncResult result)  
  28.         {  
  29.             AsyncMethodCaller caller = (AsyncMethodCaller)((AsyncResult)result).AsyncDelegate;  
  30.             // 調(diào)用EndInvoke去等待異步調(diào)用完成并且獲得返回值  
  31.             // 如果異步調(diào)用尚未完成,則 EndInvoke 會一直阻止調(diào)用線程,直到異步調(diào)用完成  
  32.             string resultvalue = caller.EndInvoke(result);  
  33.             //sc.Post(ShowState,resultvalue);  
  34.             richTextBox1.Invoke(showStateCallback, resultvalue);  
  35.         }  
  36.  
  37.         // 顯示結(jié)果到richTextBox  
  38.         private void ShowState(object result)  
  39.         {  
  40.             richTextBox1.Text = result.ToString();  
  41.             btnClick.Enabled = true;  
  42.         }  
  43.  
  44.         // 顯示結(jié)果到richTextBox  
  45.         //private void ShowState(string result)  
  46.         //{  
  47.         //    richTextBox1.Text = result;  
  48.         //    btnClick.Enabled = true;  
  49.         //}  
  50.         #endregion 

運行的結(jié)果為:

#p#

四、C# 5.0 提供的async和await使異步編程更簡單

上面部分演示了使用傳統(tǒng)的異步編程模型(APM)來解決同步代碼所存在的問題,然而在.NET 2.0,.NET 4.0和.NET 4.5中,微軟都有推出新的方式來解決同步代碼的問題,他們分別為基于事件的異步模式,基于任務(wù)的異步模式和提供async和await關(guān)鍵字來對異步編程支持。關(guān)于前兩種異步編程模式,在我前面的文章中都有介紹,大家可以查看相關(guān)文章進行詳細地了解,本部分就C# 5.0中的async和await這兩個關(guān)鍵字如何實現(xiàn)異步編程的問題來給大家介紹下。下面通過代碼來了解下如何使用async和await關(guān)鍵字來實現(xiàn)異步編程,并且大家也可以參看前面的博客來對比理解使用async和await是異步編程更簡單。

  1. private async void btnClick_Click(object sender, EventArgs e)  
  2.         {  
  3.             long length = await AccessWebAsync();  
  4.              
  5.             // 這里可以做一些不依賴回復(fù)的操作  
  6.             OtherWork();  
  7.  
  8.             this.richTextBox1.Text += String.Format("\n 回復(fù)的字節(jié)長度為:  {0}.\r\n", length);  
  9.             txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();  
  10.         }  
  11.  
  12.         // 使用C# 5.0中提供的async 和await關(guān)鍵字來定義異步方法  
  13.         // 從代碼中可以看出C#5.0 中定義異步方法就像定義同步方法一樣簡單。  
  14.         // 使用async 和await定義異步方法不會創(chuàng)建新線程,  
  15.         // 它運行在現(xiàn)有線程上執(zhí)行多個任務(wù).  
  16.         // 此時不知道大家有沒有一個疑問的?在現(xiàn)有線程上(即UI線程上)運行一個耗時的操作時,  
  17.         // 為什么不會堵塞UI線程的呢?  
  18.         // 這個問題的答案就是 當編譯器看到await關(guān)鍵字時,線程會  
  19.         private async Task<long> AccessWebAsync()  
  20.         {  
  21.             MemoryStream content = new MemoryStream();  
  22.  
  23.             // 對MSDN發(fā)起一個Web請求  
  24.             HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/"as HttpWebRequest;  
  25.             if (webRequest != null)  
  26.             {  
  27.                 // 返回回復(fù)結(jié)果  
  28.                 using (WebResponse response = await webRequest.GetResponseAsync())  
  29.                 {  
  30.                     using (Stream responseStream = response.GetResponseStream())  
  31.                     {  
  32.                         await responseStream.CopyToAsync(content);  
  33.                     }  
  34.                 }  
  35.             }  
  36.  
  37.             txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString() ;  
  38.             return content.Length;  
  39.         }  
  40.  
  41.         private void OtherWork()  
  42.         {  
  43.             this.richTextBox1.Text += "\r\n等待服務(wù)器回復(fù)中.................\n";  
  44.         } 

運行結(jié)果如下:

五、async和await關(guān)鍵字剖析

我們對比下上面使用async和await關(guān)鍵字來實現(xiàn)異步編程的代碼和在第二部分的同步代碼,有沒有發(fā)現(xiàn)使用async和await關(guān)鍵字的異步實現(xiàn)和同步代碼的實現(xiàn)很像,只是異步實現(xiàn)中多了async和await關(guān)鍵字和調(diào)用的方法都多了async后綴而已。正是因為他們的實現(xiàn)很像,所以我在第四部分才命名為使用 async和await使異步編程更簡單,就像我們在寫同步代碼一樣,并且代碼的coding思路也是和同步代碼一樣,這樣就避免考慮在APM中委托的回調(diào)等復(fù)雜的問題,以及在EAP中考慮各種事件的定義。從代碼部分我們可以看出async和await的使用確實很簡單,我們就如在寫同步代碼一般,但是我很想知道編譯器到底給我們做了怎樣的處理的?并且從運行結(jié)果可以發(fā)現(xiàn),運行異步方法的線程和GUI線程的ID是一樣的,也就是說異步方法的運行在GUI線程上,所以就不用像APM中那樣考慮跨線程訪問的問題了(因為通過委托的BeginInvoke方法來進行回調(diào)方法時,回調(diào)方法是在線程池線程上執(zhí)行的)。下面就用反射工具看看編譯器把我們的源碼編譯成什么樣子的:

對于按鈕點擊事件的代碼來說,編譯器生成的背后代碼卻是下面這樣的,完全和我們源碼中的兩個樣:

  1. // 編譯器為按鈕Click事件生成的代碼  
  2. private void btnClick_Click(object sender, EventArgs e)  
  3. {  
  4.     <btnClick_Click>d__0 d__;  
  5.     d__.<>4__this = this;  
  6.     d__.sender = sender;  
  7.     d__.e = e;  
  8.     d__.<>t__builder = AsyncVoidMethodBuilder.Create();  
  9.     d__.<>1__state = -1;  
  10.     d__.<>t__builder.Start<<btnClick_Click>d__0>(ref d__);  

看到上面的代碼,作為程序員的我想說——編譯器你怎么可以這樣呢?怎么可以任意篡改我的代碼呢?這樣不是侵犯我的版權(quán)了嗎?你要改最起碼應(yīng)該告訴我一聲吧,如果我的源碼看到它在編譯器中的實現(xiàn)是上面那樣的,我相信我的源碼會說——難道我中了世間上最惡毒的面目全非腳嗎? 好吧,為了讓大家更好地理清編譯器背后到底做了什么事情,下面就順著上面的代碼摸瓜,我也來展示耍一套還我漂漂拳來幫助大家找到編譯器代碼和源碼的對應(yīng)關(guān)系。我的分析思路為:

1、提出問題——我的click事件的源碼到哪里去了呢?從編譯器代碼我們可以看到,前面的7句代碼都是對某個類進行賦值的操作,最真正起作用的就是最后Start方法的調(diào)用。這里又產(chǎn)生了幾個疑問——<btnClick_Click>d__0是什么類型? 該類型中的<>t__builder字段類型的Start方法到底是做什么用的? 有了這兩個疑問,我們就點擊<btnClick_Click>d__0(反射工具可以讓我們直接點擊查看)來看看它是什么類型

#p#

  1. // <btnClick_Click>d__0類型的定義,從下面代碼可以看出它是一個結(jié)構(gòu)體  
  2. // 該類型是編譯器生成的一個嵌入類型  
  3. // 看到該類型的實現(xiàn)有沒有讓你聯(lián)想到什么?  
  4. private struct <btnClick_Click>d__0 : IAsyncStateMachine  
  5. {  
  6.     // Fields  
  7.     public int <>1__state;  
  8.     public Form1 <>4__this;  
  9.     public AsyncVoidMethodBuilder <>t__builder;  
  10.     private object <>t__stack;  
  11.     private TaskAwaiter<long> <>u__$awaiter2;  
  12.     public long <length>5__1;  
  13.     public EventArgs e;  
  14.     public object sender;  
  15.  
  16.     // Methods  
  17.     private void MoveNext()  
  18.     {  
  19.         try 
  20.         {  
  21.             TaskAwaiter<long> CS$0$0001;  
  22.             bool <>t__doFinallyBodies = true;  
  23.             switch (this.<>1__state)  
  24.             {  
  25.                 case -3:  
  26.                     goto Label_010E;  
  27.  
  28.                 case 0:  
  29.                     break;  
  30.  
  31.                 default:  
  32.             // 獲取用于等待Task(任務(wù))的等待者。你要知道某個任務(wù)是否完成,我們就需要一個等待者對象對該任務(wù)進行一個監(jiān)控,所以微軟就定義了一個等待者對象的  
  33.             // 從這里可以看出,其實async和await關(guān)鍵字背后的實現(xiàn)原理是基于任務(wù)的異步編程模式(TAP)  
  34.                     // 這里代碼是在線程池線程上運行的  
  35.                     CS$0$0001 = this.<>4__this.AccessWebAsync().GetAwaiter();  
  36.             // 如果任務(wù)完成就調(diào)轉(zhuǎn)到Label_007A部分的代碼  
  37.                     if (CS$0$0001.IsCompleted)  
  38.                     {  
  39.                         goto Label_007A;  
  40.                     }  
  41.              
  42.                     // 設(shè)置狀態(tài)為0為了退出回調(diào)方法。  
  43.                     this.<>1__state = 0;  
  44.                     this.<>u__$awaiter2 = CS$0$0001;  
  45.             // 這個代碼是做什么用的呢?讓我們帶著問題看下面的分析  
  46. this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter<long>, Form1.<btnClick_Click>d__0>(ref CS$0$0001, ref this);  
  47.                     <>t__doFinallyBodies = false;  
  48.             // 返回到調(diào)用線程,即GUI線程,這也是該方法不會堵塞GUI線程的原因,不管任務(wù)是否完成都返回到GUI線程  
  49.                     return;  
  50.             }  
  51.             // 當任務(wù)完成時,不會執(zhí)行下面的代碼,會直接執(zhí)行Label_007A中代碼  
  52.             CS$0$0001 = this.<>u__$awaiter2;  
  53.             this.<>u__$awaiter2 = new TaskAwaiter<long>();  
  54.             // 為了使再次回調(diào)MoveNext代碼  
  55.             this.<>1__state = -1;  
  56.         Label_007A:  
  57.             // 下面代碼是在GUI線程上執(zhí)行的  
  58.             CS$0$0001 = new TaskAwaiter<long>();  
  59.             long CS$0$0003 = CS$0$0001.GetResult();  
  60.             this.<length>5__1 = CS$0$0003;  
  61.         // 我們源碼中的代碼這里的  
  62.             this.<>4__this.OtherWork();  
  63.             this.<>4__this.richTextBox1.Text = this.<>4__this.richTextBox1.Text + string.Format("\n 回復(fù)的字節(jié)長度為:  {0}.\r\n"this.<length>5__1);  
  64.             this.<>4__this.txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();  
  65.         }  
  66.         catch (Exception <>t__ex)  
  67.         {  
  68.             this.<>1__state = -2;  
  69.             this.<>t__builder.SetException(<>t__ex);  
  70.             return;  
  71.         }  
  72.     Label_010E:  
  73.         this.<>1__state = -2;  
  74.         this.<>t__builder.SetResult();  
  75.     }  
  76.  
  77.     [DebuggerHidden]  
  78.     private void SetStateMachine(IAsyncStateMachine param0)  
  79.     {  
  80.         this.<>t__builder.SetStateMachine(param0);  
  81.     }  

如果你看過我的迭代器專題的話,相信你肯定可以聯(lián)想到該結(jié)構(gòu)體就是一個迭代器的一個實現(xiàn),其主要方法就是MoveNext方法。從上面的代碼的注釋應(yīng)該可以幫助我們解決在第一步提到的第一個問題,即<btnClick_Click>d__0是什么類型,下面就分析下第二個問題,從<btnClick_Click>d__0結(jié)構(gòu)體的代碼中可以發(fā)現(xiàn)<>t__builder的類型是AsyncVoidMethodBuilder類型,下面就看看它的Start方法的解釋——運行關(guān)聯(lián)狀態(tài)機的生成器,即調(diào)用該方法就可以開始運行狀態(tài)機,運行狀態(tài)機指的就是執(zhí)行MoveNext方法(MoveNext方法中有我們源碼中所有代碼,這樣就把編譯器生成的Click方法與我們的源碼關(guān)聯(lián)起來了)。從上面代碼注釋中可以發(fā)現(xiàn),當該MoveNext被調(diào)用時會立即還回到 GUI線程中,同時也有這樣的疑問——剛開始調(diào)用MoveNext方法時,任務(wù)肯定是還沒有被完成的,但是我們輸出我們源碼中的代碼,必須等待任務(wù)完成(因為任務(wù)完成才能調(diào)轉(zhuǎn)到Label_007A中的代碼),此時我們應(yīng)該需要回調(diào)MoveNext方法來檢查任務(wù)是否完成,(就如迭代器中的,我們需要使用foreach語句一直調(diào)用MoveNext方法),然而我們在代碼卻沒有找到回調(diào)的任何代碼啊? 對于這個疑問,回調(diào)MoveNext方法肯定是存在的,只是首次看上面代碼的朋友還沒有找到類似的語句而已,上面代碼注釋中我提到了一個問題——這個代碼是做什么用的呢?讓我們帶著問題看下面的分析,其實注釋下面的代碼就是起到回調(diào)MoveNext方法的作用,AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted<TAwaiter, TStateMachine> 方法就是調(diào)度狀態(tài)機去執(zhí)行MoveNext方法,從而也就解決了回調(diào)MoveNext的疑問了。

相信大家從上面的解釋中可以找到源碼與編譯器代碼之間的對應(yīng)關(guān)系了吧, 但是我在分析完上面的之后,又有一個疑問——當任務(wù)完成時,是如何退出MoveNext方法的呢?總不能讓其一直回調(diào)吧,從上面的代碼的注釋可以看出,當任務(wù)執(zhí)行完成之后,會把<>1__state設(shè)置為0,當下次再回調(diào)MoveNext方法時就會直接退出方法,然而任務(wù)沒完成之前,同樣也會把<>1__state設(shè)置為0,但是Switch部分后面的代碼又把<>1__state設(shè)置為-1,這樣就保證了在任務(wù)沒完成之前,MoveNext方法可以被重復(fù)回調(diào),當任務(wù)完成之后,<>1__state設(shè)置為-1的代碼將不會執(zhí)行,而是調(diào)轉(zhuǎn)到 Label_007A部分。

經(jīng)過上面的分析之后,相信大家也可以耍出一套還我漂漂拳去分析異步方法AccessWebAsync(),其分析思路是和btnClick_Click的分析思路是一樣的.這里就不重復(fù)啰嗦了。

分析完之后,下面再分享下幾個關(guān)于async和await常問的問題

問題一:是不是寫了async關(guān)鍵字的方法就代表該方法是異步方法,不會堵塞線程呢?

答: 不是的,對于只標識async關(guān)鍵字的(指在方法內(nèi)沒有出現(xiàn)await關(guān)鍵字)的方法,調(diào)用線程會把該方法當成同步方法一樣執(zhí)行,所以然而會堵塞GUI線程,只有當async和await光劍子同時出現(xiàn),該方法才被轉(zhuǎn)換為異步方法處理。

問題二:“async”關(guān)鍵字會導(dǎo)致調(diào)用方法用線程池線程運行嗎?

答: 不會,被async關(guān)鍵字標識的方法不會影響方法是同步還是異步運行并完成,而是,它使方法可被分割成多個片段,其中一些片段可能異步運行,這樣這個方法可能異步完成。這些片段界限就出現(xiàn)在方法內(nèi)部顯示使用”await”關(guān)鍵字的位置處。所以,如果在標記了”async”的方法中沒有顯示使用”await”,那么該方法只有一個片段,并且將以同步方式運行并完成。在await關(guān)鍵字出現(xiàn)的前面部分代碼和后面部分代碼都是同步執(zhí)行的(即在調(diào)用線程上執(zhí)行的,也就是GUI線程,所以不存在跨線程訪問控件的問題),await關(guān)鍵處的代碼片段是在線程池線程上執(zhí)行。總結(jié)為——使用async和 await關(guān)鍵字實現(xiàn)的異步方法,此時的異步方法被分成了多個代碼片段去執(zhí)行的,而不是像之前的異步編程模型(APM)和EAP那樣,使用線程池線程去執(zhí)行一整個方法

關(guān)于更多async和await關(guān)鍵字的常問問題可以查看——Async/Await FAQ和中文翻譯——(譯)關(guān)于async與await的FAQ

六、小結(jié)

寫到這里本專題的內(nèi)容就介紹到這里的,并且我也會把本專題的內(nèi)容同步到之前的C#基礎(chǔ)知識系列文章索引,這樣我的C#特性系列也就完整了,并且該專題也是異步編程的最后一篇專題,在后面的專題將為大家實現(xiàn)一個類似迅雷的多任務(wù)多線程下載器,對于這個專題可能會用到并行編程的內(nèi)容,所以接下面我為為大家分享下并行編程的內(nèi)容。

本專題所有源碼下載:ASyncAndAwaitTestProject.zip

原文鏈接:http://www.cnblogs.com/zhili/archive/2013/05/15/Csharp5asyncandawait.html

責任編輯:林師授 來源: 博客園
相關(guān)推薦

2024-06-25 08:33:48

2021-02-09 09:53:11

C#多線程異步

2014-07-15 10:08:42

異步編程In .NET

2024-10-07 08:28:03

WPFUI應(yīng)用程序

2016-12-14 15:05:08

C#異步編程

2021-06-28 08:10:59

JavaScript異步編程

2024-05-16 11:04:06

C#異步編程編程

2009-08-26 17:10:09

C# 3.5新特性

2024-12-23 08:00:45

2023-12-12 13:38:00

Java異步編程

2024-11-11 11:33:57

2017-08-02 14:17:08

前端asyncawait

2015-09-16 15:11:58

C#異步編程

2021-10-12 17:47:22

C# TAP異步

2025-04-08 00:22:00

C#異步編程

2021-07-24 13:16:31

Android 代碼操作系統(tǒng)

2022-06-05 23:28:50

TypeScripinfer類型

2009-08-19 16:51:14

C# 4.0 dyna

2009-08-27 16:24:48

擴展方法C# 3.0新特性

2009-05-26 16:12:43

Visual StudC#命名
點贊
收藏

51CTO技術(shù)棧公眾號

小毛片在线观看| 亚洲综合免费观看高清完整版| 91精品国产高清久久久久久| 久久久久亚洲无码| 中文字幕在线视频久| 99久久99久久久精品齐齐 | 成人bbav| 国产喂奶挤奶一区二区三区| 国产综合香蕉五月婷在线| 在线观看成人毛片| 国产欧美日韩精品一区二区免费| 欧美在线|欧美| 成年人深夜视频| 性感美女福利视频| 日本女人一区二区三区| 欧美黑人xxx| 影音先锋制服丝袜| 都市激情久久| 色94色欧美sute亚洲线路二| 中文字幕av日韩精品| 亚州男人的天堂| 国产专区欧美精品| 国产精品爱久久久久久久| 精品无码久久久久久久久| 日韩大胆成人| 日韩免费观看高清完整版在线观看| 韩国日本在线视频| 成人超碰在线| 亚洲色图视频免费播放| 亚洲 日韩 国产第一区| 蜜桃成人在线视频| 不卡欧美aaaaa| 95av在线视频| 久草热在线观看| 午夜在线视频观看日韩17c| 欧美多人爱爱视频网站| 成人欧美一区二区三区黑人一 | 亚洲美女免费精品视频在线观看| 一卡二卡三卡四卡五卡| 素人一区二区三区| 欧美性20hd另类| 成人黄色大片网站| 午夜在线激情影院| 国产拍揄自揄精品视频麻豆| 欧美在线日韩精品| 亚洲第一免费视频| 国产一区二区美女诱惑| 成人精品网站在线观看| 天堂在线免费观看视频| 在线欧美福利| 欧美国产日韩视频| 久久久久成人精品无码| 欧美激情综合| 草民午夜欧美限制a级福利片| 国产jk精品白丝av在线观看| 嫩草影视亚洲| 亚洲日韩中文字幕在线播放| 一出一进一爽一粗一大视频| 日本精品影院| 亚洲性69xxxbbb| 精品人妻中文无码av在线| 欧美极品在线观看| 亚洲视频在线观看免费| 李宗瑞91在线正在播放| 精品国产91| 在线观看欧美成人| av黄色在线免费观看| 先锋影音国产精品| 一区二区三区视频免费| jizz18女人高潮| 98精品久久久久久久| 久久精品最新地址| 欧美一区免费观看| 激情丁香综合| 欧美自拍视频在线| 色老头一区二区| 久久99最新地址| 91精品免费| 欧美视频xxx| 成人免费观看av| 久久综合中文色婷婷| 91免费在线| 亚洲欧洲日产国码二区| 99久久久无码国产精品性色戒| 在线观看的网站你懂的| 婷婷久久综合九色综合绿巨人| av在线观看地址| 五月激情久久| 日韩欧美一二三四区| 奇米777第四色| 第一会所亚洲原创| 欧美老女人xx| 精品免费囯产一区二区三区 | 牛牛国产精品| 欧美日韩第一页| 日韩毛片一区二区三区| 亚洲欧美日韩视频二区| 成人黄色短视频在线观看| 国内老熟妇对白xxxxhd| 2020国产精品自拍| 99热都是精品| 水蜜桃在线视频| 欧美一区二区视频在线观看2022| 双性尿奴穿贞c带憋尿| 91成人精品| 日韩av电影国产| 亚洲精品一区二区三区新线路| 国产亚洲自拍一区| 欧美日韩中文字幕在线播放| 午夜日韩成人影院| 精品久久人人做人人爰| 欧美老女人性生活视频| 尹人成人综合网| 成人xxxxx| 无码精品在线观看| 国产精品美女一区二区在线观看| 国产手机免费视频| 国产精品一级在线观看| 一区二区三区日韩在线| 久久久夜色精品| 精品一区二区综合| 久久久久久精| 成人三级小说| 精品日韩在线观看| 很污很黄的网站| 三级欧美在线一区| 精品日韩欧美| 黄色成人影院| 欧美在线三级电影| 亚洲天堂av网站| 午夜精品国产| 成人两性免费视频| 国产福利在线视频| 精品人伦一区二区三区蜜桃网站| 精品人妻一区二区乱码| 91成人网在线观看| 国产日韩欧美电影在线观看| 国产视频福利在线| 欧美性69xxxx肥| av电影在线播放| 欧美精品首页| 91av免费看| 中文字幕伦理免费在线视频 | av在线日韩国产精品| 欧美午夜片欧美片在线观看| 性生生活大片免费看视频| 成人黄色av| 国产精品丝袜久久久久久不卡| 裸体xxxx视频在线| 色哟哟国产精品免费观看| 熟妇高潮精品一区二区三区| 欧美aⅴ99久久黑人专区| 91网站在线看| 婷婷色在线资源| 精品剧情v国产在线观看在线| 久久亚洲AV无码| 看电视剧不卡顿的网站| 日韩精品电影网站| 精品国产黄a∨片高清在线| 最好看的2019的中文字幕视频| 中文字幕乱码人妻无码久久| 国产精品国产成人国产三级| 亚洲精品怡红院| 日韩1区在线| 91精品中国老女人| 久久不射影院| 日韩一区二区三区精品视频| 国产主播在线播放| a亚洲天堂av| 青青青在线视频播放| 精品欠久久久中文字幕加勒比| 97精品一区二区三区| 婷婷综合激情网| 色噜噜狠狠成人中文综合| 精品人伦一区二区| 精品一区二区三区蜜桃| 小说区视频区图片区| 日韩精品中文字幕吗一区二区| 中文字幕在线视频日韩| 国产在成人精品线拍偷自揄拍| 国产欧美日韩不卡| www.久久com| 欧美日韩三级| 99视频在线免费观看| 欧美性video| 亚洲欧美制服中文字幕| 一区二区三区黄| 日韩一区欧美一区| 污污污www精品国产网站| 日韩有码一区二区三区| 麻豆久久久9性大片| 黑人一区二区三区| 久久久女女女女999久久| 精品欧美不卡一区二区在线观看| 91精品国产91久久久久久一区二区 | 日韩欧美一区二区三区四区 | 狠狠色伊人亚洲综合网站色| 韩国成人漫画| 欧美大奶子在线| 色一情一乱一区二区三区| 欧美三级韩国三级日本三斤 | 成人全视频高清免费观看| 日韩亚洲欧美在线观看| 久久久黄色大片| 亚洲欧美激情视频在线观看一区二区三区| 午夜久久久久久久| 国产一区二区导航在线播放| 亚洲熟女乱色一区二区三区| 在线中文一区| 亚洲精品中文字幕在线| 蜜桃tv一区二区三区| 2022国产精品| 亚洲日本免费电影| 青草成人免费视频| 五月天婷婷在线视频| 亚洲欧美综合精品久久成人| 国产欧美久久久| 色婷婷精品久久二区二区蜜臂av | 欧美丝袜美女中出在线| 清纯粉嫩极品夜夜嗨av| 成人看片黄a免费看在线| 一区二区三区四区毛片| 日本强好片久久久久久aaa| 国产av无码专区亚洲精品| 91精品二区| 亚洲午夜激情| 日韩人体视频| 国精产品99永久一区一区| 日韩免费va| 欧美在线视频网| 在线电影福利片| 一本色道久久88精品综合| 欧洲天堂在线观看| 日韩精品视频免费| 国产又爽又黄网站亚洲视频123| 日韩欧美国产系列| 国产真人无遮挡作爱免费视频| 亚洲午夜免费视频| 强行糟蹋人妻hd中文| 亚洲欧美成人一区二区三区| 国产免费无遮挡吸奶头视频| 久久女同互慰一区二区三区| 中文字幕一区二区三区人妻在线视频 | 亚洲丝袜美腿综合| 男人的午夜天堂| 国产精品福利一区| 性生交大片免费全黄| 国产精品水嫩水嫩| 91成人在线免费视频| 久久影院午夜片一区| 毛茸茸free性熟hd| 91香蕉国产在线观看软件| 亚洲视频在线播放免费| 99久久99久久精品免费看蜜桃| 荫蒂被男人添免费视频| 国产在线一区观看| 成人啪啪18免费游戏链接| 成人av一区二区三区| www.88av| 久久久久久黄色| 日韩福利在线视频| 中文字幕在线免费不卡| 女同久久另类69精品国产| 久久精品男人天堂av| 成人做爰69片免网站| 亚洲欧美成aⅴ人在线观看 | 99riav国产精品| 免费在线观看亚洲视频| 日本91福利区| www.日本久久| 成人久久久精品乱码一区二区三区| 宇都宫紫苑在线播放| 91尤物视频在线观看| 女同性恋一区二区三区| 国产日韩欧美在线一区| 蜜桃久久精品成人无码av| 《视频一区视频二区| 国产无遮挡又黄又爽在线观看| 色噜噜夜夜夜综合网| 国产成a人亚洲精v品无码| 亚洲国产中文字幕在线观看| 免费a在线观看| 大胆人体色综合| 免费在线小视频| 成人免费激情视频| 国产精区一区二区| 国产精品一区二区久久国产| av网站在线观看免费| 亚洲成年人影院在线| 人操人视频在线观看| 久久精品99久久久香蕉| 春色校园综合激情亚洲| 国产精品一区二区久久国产| 国内精品免费| 日韩免费三级| 激情综合在线| 99热一区二区| 国产成人午夜精品影院观看视频 | 亚洲我射av| 国产精品视频久| 老司机精品视频在线播放| 国产一区免费观看| 日韩成人综合| 欧美日韩亚洲第一| 国产在线精品一区二区夜色| 国产精品成人一区二区三区电影毛片| 国产女人18水真多18精品一级做 | 国产精品日韩久久久| 国产原创中文在线观看| 国精产品一区一区三区mba桃花| 中文字幕无码人妻少妇免费| ●精品国产综合乱码久久久久| 老熟妇一区二区三区| 在线成人免费观看| 国产中文字幕在线播放| 欧美精品www在线观看| 亚洲欧美在线综合| 欧美精品七区| 中文久久精品| 污视频网址在线观看| 粉嫩蜜臀av国产精品网站| 免费成人美女女在线观看| 日本韩国视频一区二区| 四虎影视2018在线播放alocalhost| 色老头一区二区三区| 欧美巨大xxxx做受沙滩| 国产日韩欧美在线| 91国内精品白嫩初高生| 成人午夜免费剧场| 久久精品免费观看| av电影在线不卡| 欧美性生交xxxxx久久久| www.av88| 色哟哟亚洲精品一区二区| 亚洲男人av| 成人性色av| 亚洲女同另类| 午夜激情视频网| 亚洲欧洲综合另类| 国产三级在线观看视频| 色午夜这里只有精品| 亚洲精品777| 综合网五月天| 日韩激情视频在线观看| 欧洲美一区二区三区亚洲 | 好吊妞无缓冲视频观看| 国产成人免费视频| 波多野结衣爱爱视频| 欧美日韩性生活| 久久久久久国产精品免费无遮挡 | 我要看一级黄色大片| 国产三级一区二区| 日日夜夜操视频| 欧美成人伊人久久综合网| 天使と恶魔の榨精在线播放| 91视频免费在线| 精品动漫av| 最新中文字幕日本| 精品电影在线观看| 黄色三级网站在线观看| 亚洲97在线观看| 成人爽a毛片| 欧美日韩一区二区在线免费观看| 久久久久久一二三区| 波多野结衣家庭主妇| 最近2019中文字幕在线高清| 色综合桃花网| 色综合电影网| 麻豆精品在线视频| 亚洲天堂黄色片| 亚洲福利视频久久| 在线看的毛片| 亚洲第一精品区| 成人精品高清在线| 国产福利拍拍拍| 最近2019中文字幕第三页视频| 免费一级欧美在线大片| 免费久久久久久| 91麻豆免费看| 97在线公开视频| 91精品国产91久久久| 成人av二区| 欧类av怡春院| 欧美精品粉嫩高潮一区二区| 国产粉嫩在线观看| 欧美视频观看一区| 日本不卡视频在线| 久久久久久久久久久久久久久久久| 亚洲女人被黑人巨大进入al| 九七影院97影院理论片久久| 成年人午夜免费视频| 国产精品久久毛片av大全日韩| 精品久久久久中文慕人妻| 日韩美女在线看| 午夜国产欧美理论在线播放| 中文字幕成人动漫| 亚洲精品在线免费播放| 巨胸喷奶水www久久久免费动漫| 黄色www在线观看| 久久先锋影音av鲁色资源|