C# TAP異步編程(Task/async/await)總結

C#中有個很好用的東西,TAP異步編程(Task-based Asynchronous Pattern),是目前C#推薦的異步編程模型。它基于 System.Threading.Tasks.Task 和 async/await 關鍵字,旨在簡化異步代碼的編寫、調試和維護。TAP 是現代 .NET 應用開發中最常用、最推薦的異步編程方式。
要實現TAP,有三個基本元素:Task、async和await。

  • Task: 表示一個異步操作,可能沒有返回值(Task)或有返回值(Task<T>
  • async: 標記一個方法為異步
  • await: 用于等待一個異步操作完成,不會阻塞當前線程。

在Winform中,使用好TAP編程,可以方便的將異步回調操作變為同步,且不會阻塞UI線程! 非常優雅。

千問3給出的TAP優勢:

特性說明
簡化異步代碼使用 async/await 避免了復雜的回調嵌套(回調地獄)。
線程友好不會阻塞主線程(如 UI 線程),提升用戶體驗。
異常處理統一異常可以通過 try/catch 捕獲,不需要額外的錯誤回調。
取消支持支持通過 CancellationToken 安全取消異步操作。
上下文感知通過 SynchronizationContext 自動恢復執行上下文(如 UI 線程)

1.回調封裝為異步

回調的關鍵是需要有key來識別是哪次調用!
通過TaskCompletionSource來封裝回調執行時傳輸的結果數據。
通過await 一個Task實現阻塞等待。
基本代碼如下:

public static class CallBackAsync{// 存儲異步任務的上下文private static readonly ConcurrentDictionary<int, TaskCompletionSource<int>> _pendingTasks = new ConcurrentDictionary<int, TaskCompletionSource<int>>();// 回調中調用public static void OnCallBackAsync(int key, int result){if (_pendingTasks.TryRemove(key, out var tcs)){tcs.TrySetResult(result);//這里會激發await,并返回結果}}// 異步調用public static async Task<int> ChannelCtrlAsync(int key){var tcs = new TaskCompletionSource<int>();// 緩存任務上下文_pendingTasks[key] = tcs;// 調用原生同步方法int ret = NativeFunc(key);if (ret != 0){_pendingTasks.TryRemove(key, out _);tcs.TrySetException(new Exception($"{ret}")); //通過異常碼返回錯誤!}return await tcs.Task; //關鍵點}// 原生方法public static int NativeFunc(int key){Console.WriteLine("NativeFunc");//異常情況//return -1;//線程中模擬回調Task.Run(() =>{OnCallBackAsync(1, 99);});return 0;}}

這里用ConcurrentDictionary字典封裝了key和TaskCompletionSource的上下文信息,異步調用時要創建一份,回調時進行查找并刪除。
注意當原生調用立即返回錯誤且不進回調時,產生的錯誤碼沒法通過TaskCompletionSource傳出,此時可通過異常機制來輸出。

按鈕調用的實現:

private async void button1_Click(object sender, EventArgs e) //必須async標記{try{var result = await CallBackAsync.ChannelCtrlAsync(1).ConfigureAwait(true); // 恢復UI上下文//繼續干其他事情,UI不會阻塞}catch (Exception ex){//表示底層調用直接返回了錯誤碼Console.WriteLine($"底層直接返回,返回值:{ex.Message}");}}

2.阻塞調用封裝

此時無需TaskCompletionSource去手動等待,比如串口的阻塞式異步:

public async Task SendDataAsync(string strText){return await Task.Run(() =>{m_Port.Write(strText);});}

3.任務取消

通過傳入參數CancellationTokenSource 對象,可以在外部調用Cancel()方法取消任務。

public async Task SendXXXAsync(string strText, CancellationTokenSource cts){return await Task.Run(() =>{while(1){if (cts != null && cts.Token.IsCancellationRequested){return;}m_Port.Write(部分數據); //循環發送使用}});}

4.超時處理

var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3));
var completedTask = await Task.WhenAny(task, timeoutTask);
if (completedTask == timeoutTask)
{// 超時處理邏輯tcs.TrySetException(new Exception("ERR_CTRL_TIMEOUT")); //通過異常碼返回錯誤!
}
return await tcs.Task;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83487.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83487.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83487.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

達夢數據庫(DM)用戶名大小寫處理規則

達夢數據庫(DM)用戶名大小寫處理規則 達夢數據庫對用戶名的處理與PostgreSQL和Oracle有所不同&#xff0c;以下是相關說明&#xff1a; 一、基本規則 默認情況下&#xff1a;達夢數據庫區分用戶名大小寫 創建的用戶名會保留原始大小寫格式連接時必須使用相同的大小寫形式 …

黑馬點評面試話術

文章目錄 1.項目介紹2. 分布式登錄功能2.1 講講登錄的整個流程2.2 集群模式session下存儲用戶信息會有啥問題&#xff1f;2.3 為什么采用redis存儲用戶信息和驗證碼2.4 redis的存儲格式怎么樣的&#xff1f;2.5 為什么采用Hash結構存儲用戶信息2.6 為什么采用雙攔截器&#xff…

MTK APEX測光系統中各變量具體的計算方式探究

目錄 一、APEX測光系統介紹 二、MTK測光系統實例介紹 三、關于測光系統的一些疑問 一、APEX測光系統介紹 詳細內容可以參考; AE(自動曝光)系統簡介

K8S的基本概念

Kubernetes是一個開源的容器編排部署管理平臺,用于管理云平臺中多個主機上的容器化應用。Kubernetes的目標是讓部署容器化的應用簡單并且高效,Kubernetes提供了應用部署、規劃、更新、維護的一種機制。 對應用開發者而言,可以把Kubernetes看成一個集群操作系統。Kubernetes…

NLP學習路線圖(三十四): 命名實體識別(NER)

一、命名實體識別(NER)是什么? 命名實體識別(Named Entity Recognition, NER)是自然語言處理中的一項關鍵序列標注任務。其核心目標是從非結構化的文本中自動識別出特定類別的名詞性短語,并將其歸類到預定義的類別中。 核心目標:找到文本中提到的命名實體,并分類。 典…

大三自學筆記:探索Hyperlane框架的心路歷程

## Day 1&#xff1a;初識 Hyperlane 在 GitHub 上發現了 Hyperlane 這個 Rust HTTP 框架&#xff0c;立刻被它的性能數據吸引。官方文檔寫著&#xff1a; > "hyperlane 是一個高性能且輕量級的 Rust HTTP 框架&#xff0c;設計目標是簡化現代 Web 服務的開發&#xff…

Java大廠面試真題:謝飛機的技術挑戰

Java大廠面試真題&#xff1a;謝飛機的技術挑戰 場景一&#xff1a;電商場景 面試官&#xff1a;在電商項目中&#xff0c;我們通常需要處理大量的并發請求。請談談你對JVM調優的理解。 謝飛機&#xff1a;嗯&#xff0c;JVM調優主要是為了提高程序的性能和穩定性。比如&…

【Docker管理工具】安裝容器管理工具Oxker

【Docker管理工具】安裝Oxker容器管理工具 一、Oxker介紹1.1 Oxker簡介1.2 Oxker功能1.3 Docker介紹 二、本地環境介紹2.1 本地環境規劃2.2 本次實踐介紹 三、本地環境檢查3.1 檢查Docker服務狀態3.2 檢查Docker版本3.3 檢查docker compose 版本 四、下載Oxker鏡像五、安裝Oxke…

產品成本分析怎么做?從0到1搭建全生命周期分析框架!

目錄 一、為什么要做產品全生命周期成本分析&#xff1f; 1.資源再分配 2.動態成本校準 3.戰略決策支持 二、產品成本分析思路 1.建立全生命周期成本追蹤 2.聯動分析關鍵指標 3.定位問題產品線 4.資源效率四象限分配 三、產品成本分析指標 1.分投入成本&#xff1a;…

機器學習與深度學習20-數學優化

目錄 前文回顧1.梯度下降的基本原理2.什么是損失函數&#xff1f;3.隨機梯度下降和小批量梯度下降4.什么是學習率5.優化算法中的收斂性6.常用的數學優化算法 前文回顧 上一篇文章鏈接&#xff1a;地址 1.梯度下降的基本原理 梯度下降&#xff08;Gradient Descent&#xff0…

Photoshop 2025 性能配置全攻略:硬件選購與軟件優化指南

一、硬件配置核心建議 根據Adobe官方要求及實測反饋&#xff0c;Photoshop 2025對硬件的需求側重CPU、內存和存儲&#xff0c;顯卡需求相對寬松&#xff0c;但特定功能&#xff08;如AI濾鏡、3D渲染&#xff09;需關注顯卡性能。 硬件類別最低配置推薦配置&#xff08;流暢運…

華為云Flexus+DeepSeek征文 | 華為云ModelArts Studio快速上手:DeepSeek-R1-0528商用服務的開通與使用

華為云FlexusDeepSeek征文 | 華為云ModelArts Studio快速上手&#xff1a;DeepSeek-R1-0528商用服務的開通與使用 引言一、ModelArts Studio平臺介紹華為云ModelArts Studio簡介ModelArts Studio主要特點 二、開通DeepSeek-R1-0528商用服務訪問ModelArts Studio控制臺DeepSeek-…

day53 神經網絡調參指南

目錄 一、引言 二、權重初始化&#xff1a;為何如此重要&#xff1f; &#xff08;一&#xff09;隨機種子&#xff1a;確保實驗的可重復性 &#xff08;二&#xff09;權重初始化的重要性 1. 神經網絡的對稱性問題 2. 避免梯度消失和梯度爆炸 &#xff08;三&#xff0…

【大模型02---Megatron-LM】

文章目錄 Megatron-LM數據并行模型并行張量并行流水線并行 3D并行 Megatron-LM Megatron是當前大模型訓練時經常使用的一種分布式并行框架&#xff0c;它通過采用DP,TP,PP等來加速模型的訓練&#xff0c;反正就是一個字&#xff0c;好。 大模型在訓練的時候&#xff0c;顯存占…

魔百和網絡機頂盒CM211-1硬件解析

先來個正面照 背面照 核芯 無線網卡 支持WiFi與藍牙 硬盤 正面內存與背面內存

Kratos 與Golang Cms的關系

Kratos 與 Golang CMS 的關系 Kratos 是 Bilibili 開源的一款輕量級 Go 語言微服務框架,專注于構建高性能、可擴展的后端服務。雖然它本身并不是一個完整的 CMS(內容管理系統),但它可以用于開發 CMS 系統的后端或 API 服務。 我們的目標是提供全面的微服務開發技術。基于…

在vue3+vite中給 Video視頻 添加字幕

Video視頻 添加字幕 方式一: 使用 track標簽template標簽中css樣式修改方式二:直接讀取.vtt文件方式一: 使用 track標簽 參考1:https://blog.csdn.net/weixin_42321819/article/details/112442773 參考2:https://blog.csdn.net/foren_whb/article/details/80810552 template標…

UE4手動實現billboard效果讓物體始終面向相機正面

一個很簡單的需求&#xff0c;但在網上竟然沒查到。首先不能用FindLookAtRotation&#xff0c;因為這是用location算的&#xff0c;是讓物體朝向相機的方向&#xff0c;而不是朝向相機的正面。區別如下圖所示&#xff1a; 然后想用billboard component&#xff0c;不過這個原生…

在阿里云上搭建n8n

0.安裝docker 0.1 刪除Docker相關源 #刪除Docker相關源 sudo rm -f /etc/yum.repos.d/docker*.repo #卸載Docker和相關的軟件包 sudo dnf -y remove \ docker-ce \ containerd.io \ docker-ce-rootless-extras \ docker-buildx-plugin \ docker-ce-cli \ docker-compose-plug…

Qt中的OpenGL (4)[紋理]

文章說明 本文是學習OpenGL的筆記,主要參考大神JoeyDeVries的LearnOpenGL第六課《紋理》,并將教程中的代碼基于Qt進行實現。 學習目標 掌握紋理基本知識掌握紋理貼圖目錄結構 |- |-- HelloTextures|--- hello_textures.cpp|--- hello_textures.h|--- main.cpp|--- CMakeLi…