C#中使用 async await TaskCompletionSource<T>实现异步逻辑同步写

Task、async 和 await 是 C# 中用于处理异步编程的关键概念。它们一起构成了异步编程的基础。

Task

Task 是表示异步操作的抽象,它属于 System.Threading.Tasks 命名空间。Task 可以表示已经完成的任务、正在运行的任务或者尚未开始的任务。通过 Task,可以执行异步操作、并发操作,以及异步等待任务完成。

async 和 await

async 和 await 关键字是异步编程的基础构造,用于简化异步代码的编写。它们通常一起使用,使得编写异步代码更加直观、易读。

async

关键字用于定义一个异步方法。异步方法可以包含 await 操作符,并且在异步执行期间可以被挂起,而不会阻塞调用线程。

await

await 操作符用于等待异步操作完成,并返回异步操作的结果。在 async 方法中,await 会将控制权返回给调用者,而不会阻塞线程,从而提高了程序的响应性。

TaskCompletionSource

TaskCompletionSource 是用于创建和控制 Task 实例的一种灵活的方式。通常情况下,Task 表示一个异步操作的结果,而 TaskCompletionSource 则允许你手动控制异步操作的完成。
tcs.SetResult(42) 来设置异步操作的结果
tcs.SetCanceled() 异步取消
tcs.SetException() 异常
TaskCompletionSource 成为一种强大的工具,用于自定义异步操作的实现和控制。

例子 直接上结果

在这里插入图片描述
以往的代码实现上都是请求一个异步操作挂载一个回调方法
使用Task可以轻松实现异步操作同步写代码

public class LoginLogic
{public async static void Call(){C2S_Login c2S_Login = new C2S_Login(){name = "wukong",password = "123456",};S2C_Login s2C_Login = await TaskLogic.Instance.Call<S2C_Login>(c2S_Login);Debug.LogError($"接收消息, id: {s2C_Login.id}, time: {s2C_Login.time}, location: {s2C_Login.location}");//这里直接处理后续逻辑}
}public class Test : MonoBehaviour
{void Start(){LoginLogic.Call();}
}

代码实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using System;
using System.Threading;namespace Game
{public interface IResponse{public int id { get; set; }}public interface IRequest{public int id { get; set; }}public class C2S_Login : IRequest{public int id { get; set; }public string name;public string password;}public class S2C_Login : IResponse{public int id { get; set; }public int time;public string token;public string location;}public class RPCInfo : IDisposable{public int id;public TaskCompletionSource<IResponse> tcs;public CancellationTokenSource cts;public void SetResult(IResponse response){tcs?.SetResult(response);}public void Dispose(){cts?.Dispose();}}public class TaskLogic{private static TaskLogic _instance;private int _id;private Dictionary<int, RPCInfo> _rpcs;//单位毫秒private const int RPC_TIMEOUT = 5000;public static TaskLogic Instance{get{if (_instance == null)_instance = new TaskLogic();return _instance;}}public TaskLogic(){Init();}public string GetName(){return "TaskLogic";}public bool Init(){_rpcs = new Dictionary<int, RPCInfo>();return true;}private async void Send(IRequest request){await Task.Run(async () =>{//这段代码只是用于模拟发送C2S_Login c2S_Login = request as C2S_Login;Debug.LogError($"发送消息, Name: {c2S_Login.name}, password: {c2S_Login.password}");//延迟一秒await Task.Delay(2000);//模拟接收S2C_Login s2C_Login = new S2C_Login(){id = request.id,time = DateTime.Now.Millisecond,location = "北京",};Recv(s2C_Login);});}public async Task<T> Call<T>(IRequest request) where T : class, IResponse, new(){Interlocked.CompareExchange(ref _id, 0, int.MaxValue);request.id = Interlocked.Increment(ref _id);//1.模拟一下发消息, 延迟1秒后调用回复Send(request);//2.等待消息返回IResponse response = await WaitTask(request);return response as T;}private Task<IResponse> WaitTask(IRequest request){TaskCompletionSource<IResponse> tcs = new TaskCompletionSource<IResponse>();CancellationTokenSource cts = new CancellationTokenSource();cts.CancelAfter(RPC_TIMEOUT);cts.Token.Register(() =>{Debug.LogError($"time out: {request}");_rpcs.Remove(request.id);});RPCInfo rpcInfo = new RPCInfo() { id = request.id, tcs = tcs, cts = cts };_rpcs.Add(request.id, rpcInfo);return rpcInfo.tcs.Task;}private void Recv(IResponse response){RPCInfo rpcInfo;if (!_rpcs.TryGetValue(response.id, out rpcInfo))return;rpcInfo.Dispose();rpcInfo.SetResult(response);_rpcs.Remove(response.id);}public void UnInit(){}public void Update(){}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你的第一个C/S程序

目录 socket服务端代码客户端代码执行结果 socket socket基础知识 服务端代码 import socket import threading import timeMSG_LENGTH 64 DISCONNECTED !CONNECTION CLOSED connections 0#定义服务器地址 server_ip socket.gethostbyname(socket.gethostname()) server…

【设计模式之美】面向对象分析方法论与实现(二):需求到接口实现的方法论

文章目录 一. 进行面向对象设计1. 划分职责>需要有哪些类2. 定义类及其属性和方法3. 定义类与类之间的交互关系4. 将类组装起来并提供执行入口 二. 如何进行面向对象编程&#xff1f;1. 接口实现2. 辩证思考与灵活应用 【设计模式之美】面向对象分析方法论与实现&#xff08…

教育场景数字化中音视频小程序的发展

教育场景数字化逐步成为刚需 2018年以来&#xff0c;国家对在线教育行业的监管收紧&#xff0c;以及受益于 5G 技术的发展&#xff0c;教育科技逐步走向成熟化和规范化。 教育行业的本质是人与人&#xff08;老师与学生、老师与家长&#xff0c;以及更多角色直接的沟通与互动…

【数据结构和算法】小行星碰撞

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 什么情况会用到栈 2.2 方法一&#xff1a;模拟 栈 三、代码 3.1 方法一&#xff1a;模拟 栈 四…

【LLM+RS】LLM在推荐系统的实践应用(华为诺亚)

note LLM用于推荐主要还是解决推荐系统加入open domain 的知识。可以基于具体推荐场景数据做SFT。学习华为诺亚-技术分享-LLM在推荐系统的实践应用。 文章目录 note一、背景和问题二、推荐系统中哪里使用LLM1. 特征工程2. 特征编码3. 打分排序 三、推荐系统中如何使用LLM四、挑…

共享WiFi贴项目加盟可以解决商家哪些痛点?

近年来&#xff0c;共享WiFi贴项目在共享商业领域引起了广泛关注。作为一种便捷的网络分享工具&#xff0c;共享WiFi贴不仅受到很多人的青睐&#xff0c;更能够为商家带来诸多实际利益。那么&#xff0c;共享WiFi贴项目加盟究竟可以解决商家哪些痛点呢&#xff1f; 共享WiFi贴为…

【C#】知识点实践序列之Lock的锁定代码块

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂之知识点实践序列》文章。 2024年第1篇文章&#xff0c;此篇文章是C#知识点实践序列之Lock知识点&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 本篇验证Lock锁定代…

Navicat(数据库可视化软件)安装教程以及连接MYSQL

Navicat安装教程以及连接MYSQL Navicat&#xff08;数据库可视化软件&#xff09;安装流程安装MySQLnavicat连接mysql数据库 Navicat&#xff08;数据库可视化软件&#xff09; Navicat 是一款专门为 MySQL 设计的可视化数据库 GUI 管理工具&#xff0c;我们可以在自己的计算机…

深入浅出Python日志打印

0.引言 在编程过程中&#xff0c;日志记录是一项非常重要的任务&#xff0c;无论是用于调试代码、记录系统运行状态&#xff0c;还是跟踪可能出现的问题&#xff0c;日志都能发挥重要作用。然而&#xff0c;许多开发者习惯使用简单的print语句来记录信息&#xff0c;这种方法虽…

ensp vlan连接(详细)

1.将需要的设备放置好 2.将设备连接起来 3.启动所有设备 4.备注好每台PC机的信息 5.配置好每台PC机 6.配置交换机1 进入配置视图&#xff0c;关闭信息提示 重命名设备 批量创建VLAN 开始配置接口 更改接口类型为ACCESS 将接口划分到对应的VLANN 配置下一个接口&#xff0c;步…

编译 nccl-tests 项目

1&#xff0c;编译 下载源代码 git clone --recursive https://github.com/NVIDIA/nccl-tests.git 编译源代码 cd nccl-tests/ make -j 2&#xff0c;运行 cd ./build/ ./all_reduce_perf --help ./all_reduce_perf -b 8 -e 256M -f 2 -g 4 效果图&#xff1a; 3&#…

说说产品经理能力模型

产品经理的能力模型应该是什么样的&#xff0c;可能100个产品人会有100种看法&#xff0c;每个人的认知都是不一样的&#xff0c;今天和大家分享下我对产品经理能力模型的总结。 前段时间&#xff0c;一个30多岁做前端开发的朋友跟我说想转行做产品&#xff0c;让我帮忙指导下…

关于Python里xlwings库对Excel表格的操作(三十)

这篇小笔记主要记录如何【如何使用“Chart类”、“Api类"和“Axes函数”为新图表设置标题文本内容、字体、字号、粗细、正斜、颜色、坐标轴主要网格线】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】…

Maple 各版本安装指南

Maple 下载链接 https://pan.baidu.com/s/11hKo1XxZGa0xv3Ivj6fbEA?pwd0531 1.鼠标右击【Maple 2023】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;【解压到 Maple 2023】。 2.打开解压后的文件夹&#xff0c;鼠标右击【Setup】选择【以管理员身…

计算机毕业设计------SSM的公寓房屋出租系统

项目介绍 该项目分为前后台&#xff0c;分为普通用户与管理员两种角色。 前台主要功能包括&#xff1a; 普通用户的注册、登录,房屋列表展示&#xff0c;租房&#xff0c;我的订单、用户中心等功能模块&#xff1b; 后台主要功能包括&#xff1a; 系统设置&#xff1a;菜单管…

航空业数字化展翅高飞,开源网安专业服务保驾护航

​某知名航空公司是中国首批民营航空公司之一&#xff0c;运营国内外航线200多条&#xff0c;也是国内民航最高客座率的航空公司之一。在数字化发展中&#xff0c;该航空公司以数据驱动决策&#xff0c;通过精细化管理、数字创新和模式优化等方式&#xff0c;实现了精准营销和个…

day58算法训练|单调栈part01

参考&#xff1a;代码随想录 单调栈的使用情况&#xff1a; 通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置&#xff0c;此时我们就要想到可以用单调栈了。时间复杂度为O(n)。 单调栈的本质是空间换时间&#xff0c;因为在遍历…

10款值得推荐的Blazor UI组件库

前言 经常看到有小伙伴在DotNetGuide技术社区交流群里问有什么好用的Blazor UI组件库推荐的&#xff0c;本文将分享一些开源、实用、美观的Blazor UI组件库&#xff0c;提供给广大C#/.NET开发者们学习和使用&#xff08;注意&#xff1a;排名不分先后&#xff0c;都是十分优秀…

Python内置类属性__module__属性的使用教程

概要 在Python中&#xff0c;每个对象都有一些内置的属性&#xff0c;这些属性提供了有关对象的一些信息。其中一个内置属性是__module__属性。__module__属性是一个字符串&#xff0c;它表示定义了类或函数的模块的名称。在本篇文章中&#xff0c;我们将详细介绍__module__属…

BUUCTF——Reverse——[GXYCTF2019]luck_guy

1、题目 2、工具 Exeinfo PE&#xff1a;查壳工具。IDA&#xff1a;是一款功能强大的反汇编工具&#xff0c;用于分析和逆向工程二进制文件。python&#xff1a;编写自动化脚本。 3、方法 下载压缩包&#xff0c;解压得到一个没有后缀的文件。 用Exeinfo PE查询该文件是否加…