非同步CTP(Async CTP)為什麼那樣工作?

来源:http://www.cnblogs.com/ldyblogs/archive/2017/09/22/Async.html
-Advertisement-
Play Games

對非同步CTP感興趣有很多原因。非同步CTP使非同步編程比以前更加容易了。它雖然沒有Rx強大,但是更容易學。非同步CTP介紹了兩個新的關鍵字,async和await。非同步方法(或Lambda表達式)必須返回void,Task或Task<TResult>。這篇文章不是介紹非同步CTP的,因為網上有很多這樣的文章 ...


對非同步CTP感興趣有很多原因。非同步CTP使非同步編程比以前更加容易了。它雖然沒有Rx強大,但是更容易學。非同步CTP介紹了兩個新的關鍵字,async和await。非同步方法(或Lambda表達式)必須返回void,Task或Task<TResult>。這篇文章不是介紹非同步CTP的,因為網上有很多這樣的文章。這篇文章的目的是把程式員開始使用Async CTP遇到的一些常見問題集中起來。

推斷返回類型

當從非同步方法返回一個值的時候,此方法體直接返回這個值,但該方法本身被聲明為返回一個Task<TResult>。當聲明一個返回甲類型的方法卻必須返回一個乙類型時,就有點“斷連”了。

// 實際語法
public async Task<int> GetValue()
{
  await TaskEx.Delay(100);
  return 13; //返回類型是 "int", 而不是"Task<int>"
}

問題來了:為什麼我不能這麼寫?

// 假想語法
public async int GetValue()
{
  await TaskEx.Delay(100);
  return 13; // 返回類型是 "int"
}
思考:該方法如何如何照顧調用者呢?非同步方法必須返回一個實際結果類型Task<TResult>的值。因此,GetValue方法會出現返回Task<TResult>的智能提示(在對象瀏覽器,Reflector等中也是這樣的)。   在設計之初,推斷返回類型已經被考慮到了,但該設計團隊已經推斷出在非同步方法中保持這種“斷連”比在代碼基上擴大這種“斷連”更好。如今這種“斷連”仍存在,但比以前更小了。該設計團隊的共識是一致的方法簽名更佳。 思考:async void 和async Task有什麼區別? 一個async Task方法就像任何其他的非同步操作一樣,只是沒有返回值。一個async void方法扮演一種高級操作。async Task方法可能被組合進其他使用using await的非同步方法。async void方法可能被用作一個事件句柄。async void方法也有其他重要的屬性:在ASP.NET上下文中,它通知web伺服器直到它返回,頁面才完成。   推斷返回類型會移除async void 和async Task間的區別:要麼所有的非同步方法是async void(阻止可組合性),要麼都是async Task(阻止它們來自事件句柄,同時對ASP.NET要有一個可選擇的方案)。

 非同步返回

  在方法聲明返回類型和方法體返回的類型之間仍有“斷連”。該設計團隊的另一個建議是:給return添加一個關鍵字來指示return返回的值,但這個也確實沒有返回什麼,如下所示:
// 假想語法
public async Task<int> GetValue()
{
  await TaskEx.Delay(100);
  async return 13; // "async return" 意味著值被包裝在Task中
}
思考:將大量的代碼從同步轉為非同步。

async return關鍵字也被考慮到了,但並沒有足夠的說服力。當把一些同步代碼轉成非同步代碼時,這尤其正確。強制人們給每個return語句添加asynchronous就好像是“不必要的忙碌”。比較而言,習慣於“斷連”更容易。

推斷“async”

async關鍵字必須用在使用了await關鍵字的方法上。然而,如果把async用在了一個沒有使用await的方法上,也會收到一個警告。

問題:為什麼async不能根據await的存在推斷出來?

//假想語法
public Task<int> GetValue()
{
  // "await" 的存在暗示這是一個 "async" 方法.
  await TaskEx.Delay(100);
  return 13;
}

思考:向後相容性和代碼可讀性

單字的await關鍵字具有太大的打破變化。在非同步方法上的多字await(如await for)或一個關鍵字之間的選擇,只是在那個方法內部啟用await關鍵字。很明顯,使用async標記方法讓人類和電腦分析起來更容易,因此設計團隊決定使用async/await對。

推斷“await”

問題:既然顯示包括async有意義(看上面),為什麼await不能根據async的存在推斷出來呢?

// 假想語法
public async Task<int> GetValue()
{
  // 暗示有"await",因為這是一個 "async" 方法.
  TaskEx.Delay(100);
  return 13;
}

思考:非同步操作的並行組合。

乍一看,推斷await推斷似乎簡化了基本的非同步操作。只要所有的等待可以按序列(如一個操作等待,然後另一個,再然後另一個)完成,這個就能很好的工作。然而,當有人考慮並行組合的時候,它崩潰了。

非同步CTP中的並行組合使用TaskEx.WhenAny 和TaskEx.WhenAll方法。這有一個簡單的例子,這個方法立即開始了兩個操作,並且等待它們完成。

// 實際語法
public async Task<int> GetValue()
{
  // 非同步檢索兩個部分的值
  // 註意此時它們是沒有等待的“not await”
  Task<int> part1 = GetValuePart1();
  Task<int> part2 = GetValuePart2();

  // 等待它們的值到達。
  await TaskEx.WhenAll(part1, part2);

  // 計算我們的結果
  int value1 = await part1; // 實際上沒有等待
  int value2 = await part2; //實際上沒有等待
  return value1 + value2;
}

為了處理並行組合,我們必須有能力說我們將不會await一個表達式。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文發表於cu:2016-08-25 參考文檔: 本文針對Nginx幾個常用特性做簡單驗證(高手請略過),通過簡單的驗證熟悉配置。 一.環境準備 1. 操作系統 CentOS-7-x86_64-Everything-1511 2. Nginx版本 Nginx-1.11.3: http://nginx ...
  • 伺服器:提供計算服務的設備。它是網路環境中的高性能電腦,它偵聽網路上的其他電腦(客戶端)提交的服務請求,並提供相應的服務。 伺服器是指管理和傳輸信息的一種電腦系統。 例如:網路游戲, 100個人同時線上,就代表有100個"客戶端", 這100個人游戲時所產生的數據變化,就傳輸到伺服器上計算並存 ...
  • 入手了Firefly-RK3288的開發板,自己從零開始搭建編譯環境開荒第一步:安裝Ubuntu12.04,使用安裝盤安裝(安裝的過程就不詳寫了,下麵貼圖) 安裝完後,更新ubuntu 第二步:從官網上下載SDK,進行編譯環境的安裝下載SDK有兩種方式,一是下載壓縮包,二是通過git下載。我選擇了下 ...
  • 第1章 linux文件屬性相關 1.1 linux文件屬性 1.2 磁碟的使用過程 1、磁碟(房子) 2、分區(劃分隔斷) 3、格式化創建文件系統(裝修) 4、掛載(安裝門窗) 5、存放文件(住人) 1、磁碟(房子) 2、分區(劃分隔斷) 3、格式化創建文件系統(裝修) 4、掛載(安裝門窗) 5、存 ...
  • 前言 1.為什麼要建域 工作組的分散管理模式不適合大型的網路環境下工作,域模式就是針對大型的網路管理需求設計的,就是共用用戶賬號,電腦賬號和安全策略的電腦集合。域中集中存儲用戶賬號的電腦就是域控器,域中用戶賬號, 電腦賬號和安全策略被存儲在域控制器上一個名為Active Directory的 ...
  • /// /// 獲取功能變數名稱的頂級功能變數名稱 /// /// /// public static string GetTopDomainName(string domain) { //https://www.safsd.asdfasdf.baidu.com.cn/ssssd... ...
  • 為什麼不用FiddlerCore? 說到FiddlerCore大家可能會比較陌生,那麼它哥Fiddler就比較熟悉了;抓包、模擬低帶寬、修改請求我平時比較常用。Fiddler的本質就是一個HTTP代理伺服器。 FiddlerCore是Fiddler去除了UI的核心組件,可以用於二次開發。如下圖所示: ...
  • 我在別的網站上下載了一個mp4格式的視頻,加到video標簽里可以正常播放, 然後我用FLV自己轉成mp4,卻提示不支持的格式和mine類型, 後來找到一篇文章 http://jingyan.baidu.com/article/49711c617a940cfa441b7cc6.html 發現了一個關 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...