ET介绍——C#更好的协程
更好的协程
上文讲了一串回调就是协程,显然这样写代码,增加逻辑,插入逻辑非常容易出错。我们需要利用异步语法把这个异步回调的形式改成同步的形式,幸好C#已经帮我们设计好了,看代码
// example2_2
class Program
{
private static int loopCount = 0; static void Main(string[] args)
{
OneThreadSynchronizationContext _ = OneThreadSynchronizationContext.Instance; Console.WriteLine($"主线程: {Thread.CurrentThread.ManagedThreadId}"); Crontine(); while (true)
{
OneThreadSynchronizationContext.Instance.Update(); Thread.Sleep(1); ++loopCount;
if (loopCount % 10000 == 0)
{
Console.WriteLine($"loop count: {loopCount}");
}
}
} private static async void Crontine()
{
await WaitTimeAsync(5000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
await WaitTimeAsync(4000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
await WaitTimeAsync(3000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
} private static Task WaitTimeAsync(int waitTime)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
Thread thread = new Thread(()=>WaitTime(waitTime, tcs));
thread.Start();
return tcs.Task;
} /// <summary>
/// 在另外的线程等待
/// </summary>
private static void WaitTime(int waitTime, TaskCompletionSource<bool> tcs)
{
Thread.Sleep(waitTime); // 将tcs扔回主线程执行
OneThreadSynchronizationContext.Instance.Post(o=>tcs.SetResult(true), null);
}
}
在这段代码里面,WaitTimeAsync方法中,我们利用了TaskCompletionSource类替代了之前传入的Action参数,WaitTimeAsync方法返回了一个Task类型的结果。WaitTime中我们把action()替换成了tcs.SetResult(true),WaitTimeAsync方法前使用await关键字,这样可以将一连串的回调改成同步的形式。这样一来代码显得十分简洁,开发起来也方便多了。
这里还有个技巧,我们发现WaitTime中需要将tcs.SetResult扔回到主线程执行,微软给我们提供了一种简单的方法,参考example2_2_2,在主线程设置好同步上下文,
// example2_2_2
SynchronizationContext.SetSynchronizationContext(OneThreadSynchronizationContext.Instance);
在WaitTime中直接调用tcs.SetResult(true)就行了,回调会自动扔到同步上下文中,而同步上下文我们可以在主线程中取出回调执行,这样自动能够完成回到主线程的操作
private static void WaitTime(int waitTime, TaskCompletionSource<bool> tcs)
{
Thread.Sleep(waitTime); tcs.SetResult(true);
}
如果不设置同步上下文,你会发现打印出来当前线程就不是主线程了,这也是很多第三方库跟.net core内置库的用法,默认不回调到主线程,所以我们使用的时候需要设置下同步上下文。其实这个设计本人觉得没有必要,交由库的开发者去实现更好,尤其是在游戏开发中,逻辑全部是单线程的,回调每次都走一遍同步上下文就显得多余了,所以ET框架提供了不使用同步上下文的实现ETTask,代码更加简洁更加高效,这个后面会讲到。
ET开源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com) qq群:474643097
ET介绍——C#更好的协程的更多相关文章
- RxHttp ,比Retrofit 更优雅的协程体验
1.前言 Hello,各位小伙伴,又见面了,回首过去,RxHttp 就要迎来一周年生日了(19年4月推出),这一年,走过来真心....真心不容易,代码维护.写文章.写文档等等,经常都是干到零点之后,也 ...
- 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页
协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...
- [转]Unity3D协程介绍 以及 使用
作者ChevyRay ,2013年9月28日,snaker7译 原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...
- Unity3D协程介绍 以及 使用
作者ChevyRay ,2013年9月28日,snaker7译 原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...
- lua编程之协程介绍
一,lua协程简介 协程(coroutine),意思就是协作的例程,最早由Melvin Conway在1963年提出并实现.跟主流程序语言中的线程不一样,线程属于侵入式组件,线程实现的系统称之为抢占式 ...
- Unity中的协程(一)
这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines 这篇文章转自:http://blog.csdn. ...
- Python协程(真才实学,想学的进来)
真正有知识的人的成长过程,就像麦穗的成长过程:麦穗空的时候,麦子长得很快,麦穗骄傲地高高昂起,但是,麦穗成熟饱满时,它们开始谦虚,垂下麦芒. --蒙田<蒙田随笔全集> *** 上篇论述了关 ...
- 阿里开源 iOS 协程开发框架 coobjc!--异步编程的问题与解决方案
阿里妹导读:刚刚,阿里巴巴正式对外开源了基于 Apache 2.0 协议的协程开发框架 coobjc,开发者们可以在 Github 上自主下载.coobjc是为iOS平台打造的开源协程开发框架,支持O ...
- PHP的生成器、yield和协程
虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究.不过公司的框架是基于php的协程实现,觉得有必要深入的瞅瞅了. 由于之前对于生成器接触不 ...
- 在PHP中使用协程实现多任务调度
PHP5.5一个比较好的新功能是加入了对迭代生成器和协程的支持.对于生成器,PHP的文档和各种其他的博客文章已经有了非常详细的讲解.协程相对受到的关注就少了,因为协程虽然有很强大的功能但相对比较复杂, ...
随机推荐
- OpenAI 的视频生成大模型Sora的核心技术详解(一):Diffusion模型原理和代码详解
标题党一下,顺便蹭一下 OpenAI Sora大模型的热点,主要也是回顾一下扩散模型的原理. 1. 简单理解扩散模型 简单理解,扩散模型如下图所示可以分成两部分,一个是 forward,另一个是 re ...
- 用Taro写一个微信小程序——Taro3路由传参
参考https://docs.taro.zone/docs/router 1.传入参数 Taro.navigateTo({ url: '/pages/page/path/name?id=2&t ...
- Jenkins流水线使用@Grab 导入Maven库
有个需求需要在pipeline中调用Java的SDK去执行业务 使用 @Grab 注解可以在Maven中导入Java 库, @Grab('org.apache.commons:commons-math ...
- OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 一个简单的Dockerfile多阶段构建go项目
From golang:1.16-alpine3.13 AS builder WORKDIR /app COPY . . RUN go build -o main main.go From alpin ...
- SQL Server 连接数据库报错 (ObjectExplorer)
报错信息 无法访问数据库 ReportServer. (ObjectExplorer) 具体错误信息: 程序位置: 在 Microsoft.SqlServer.Management.UI.VSInte ...
- 代码随想录算法训练营第三十天| 51. N皇后 37. 解数独 总结
卡哥建议:今天这三道题都非常难,那么这么难的题,为啥一天做三道? 因为 一刷 也不求大家能把这么难的问题解决,所以 大家一刷的时候,就了解一下题目的要求,了解一下解题思路,不求能直接写出 ...
- 四种色彩模式ARGB_8888、ARGB_4444、 RGB_565、 ALPHA_8
A:透明度. R:红色. G:绿色. B:蓝色. Bitmap.Config ARGB_8888:有四个8位组成,A,R,G,B各占八位,也就是各占一个字节.也就是一个像素点占4个字节,32位. Bi ...
- SpringCloud Sentinel使用
1. 简介 Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流.流量整形.熔断降级.系统负载保护.热点防护等多个维度来帮助开发者保障微服务的稳定性.替换原先Hystrix ...
- 使用Kubernetes搭建带有ik分词的Elasticsearch集群
创建好带有Ik分词的es镜像,并上传到镜像仓库中,创建镜像可参考链接中的文档 https://www.cnblogs.com/hi-lijq/p/16895206.html 编写es_cluster- ...