ET介绍——CSharp协程
什么是协程
说到协程,我们先了解什么是异步,异步简单说来就是,我要发起一个调用,但是这个被调用方(可能是其它线程,也可能是IO)出结果需要一段时间,我不想让这个调用阻塞住调用方的整个线程,因此传给被调用方一个回调函数,被调用方运行完成后回调这个回调函数就能通知调用方继续往下执行。举个例子:
下面的代码,主线程一直循环,每循环一次sleep 1毫秒,计数加一,每10000次打印一次。
private static void Main()
{
int loopCount = 0;
while (true)
{
int temp = watcherValue; Thread.Sleep(1); ++loopCount;
if (loopCount % 10000 == 0)
{
Console.WriteLine($"loop count: {loopCount}");
}
}
}
这时我需要加个功能,在程序一开始,我希望在5秒钟之后打印出loopCount的值。看到5秒后我们可以想到Sleep方法,它会阻塞线程一定时间然后继续执行。我们显然不能在主线程中Sleep,因为会破坏掉每10000次计数打印一次的逻辑。
// example2_1
class Program
{
private static int loopCount = 0; private static void Main()
{
OneThreadSynchronizationContext _ = OneThreadSynchronizationContext.Instance; WaitTimeAsync(5000, WaitTimeFinishCallback); while (true)
{
OneThreadSynchronizationContext.Instance.Update(); Thread.Sleep(1); ++loopCount;
if (loopCount % 10000 == 0)
{
Console.WriteLine($"loop count: {loopCount}");
}
}
} private static void WaitTimeAsync(int waitTime, Action action)
{
Thread thread = new Thread(()=>WaitTime(waitTime, action));
thread.Start();
} private static void WaitTimeFinishCallback()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
} /// <summary>
/// 在另外的线程等待
/// </summary>
private static void WaitTime(int waitTime, Action action)
{
Thread.Sleep(waitTime); // 将action扔回主线程执行
OneThreadSynchronizationContext.Instance.Post((o)=>action(), null);
}
}
我们在这里设计了一个WaitTimeAsync方法,WaitTimeAsync其实就是一个典型的异步方法,它从主线程发起调用,传入了一个WaitTimeFinishCallback回调方法做参数,开启了一个线程,线程Sleep一定时间后,将传过来的回调扔回到主线程执行。OneThreadSynchronizationContext是一个跨线程队列,任何线程可以往里面扔委托,OneThreadSynchronizationContext的Update方法在主线程中调用,会将这些委托取出来放到主线程执行。为什么回调方法需要扔回到主线程执行呢?因为回调方法中读取了loopCount,loopCount在主线程中也有读写,所以要么加锁,要么永远保证只在主线程中读写。加锁是个不好的做法,代码中到处是锁会导致阅读跟维护困难,很容易产生多线程bug。这种将逻辑打包成委托然后扔回另外一个线程是多线程开发中常用的技巧。
我们可能又有个新需求,WaitTimeFinishCallback执行完成之后,再想等3秒,再打印一下loopCount。
private static void WaitTimeAsync(int waitTime, Action action)
{
Thread thread = new Thread(()=>WaitTime(waitTime, action));
thread.Start();
}
private static void WaitTimeFinishCallback()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
WaitTimeAsync(3000, WaitTimeFinishCallback2);
} private static void WaitTimeFinishCallback2()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
}
我们这时还可能改需求,需要在程序启动5秒后,接下来4秒,再接下来3秒,打印loopCount,也就是上面的逻辑中间再插入一个3秒等待。
private static void WaitTimeAsync(int waitTime, Action action)
{
Thread thread = new Thread(()=>WaitTime(waitTime, action));
thread.Start();
} private static void WaitTimeFinishCallback()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
WaitTimeAsync(4000, WaitTimeFinishCallback3);
} private static void WaitTimeFinishCallback3()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
WaitTimeAsync(3000, WaitTimeFinishCallback2);
} private static void WaitTimeFinishCallback2()
{
Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
}
这样中间插入一段代码,显得非常麻烦。这里可以回答什么是协程了,其实这一串串回调就是协程。
ET开源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com) qq群:474643097
ET介绍——CSharp协程的更多相关文章
- Lua的协程和协程库详解
我们首先介绍一下什么是协程.然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复杂用法. 一.协程是什么? (1)线程 首先复习一下多线程.我们都知道线程——Thre ...
- [转载]协程-cooperative multitasking
[转载]协程三讲 http://ravenw.com/blog/2011/08/24/coroutine-part-1-defination-and-classification-of-corouti ...
- coroutine协程
如果你接触过lua这种小巧的脚本语言,你就会经常接触到一个叫做协程的神奇概念.大多数脚本语言都有对协程不同程度的支持.但是大多编译语言,如C/C++,根本就不知道这样的东西存在.当然也很多人研究如何在 ...
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
- Python协程(真才实学,想学的进来)
真正有知识的人的成长过程,就像麦穗的成长过程:麦穗空的时候,麦子长得很快,麦穗骄傲地高高昂起,但是,麦穗成熟饱满时,它们开始谦虚,垂下麦芒. --蒙田<蒙田随笔全集> *** 上篇论述了关 ...
- 异步时代-java的协程路在何方
面试官:你知道协程吗? 你:订机票的那个吗,我常用. 面试官:行,你先回去吧,到时候电话联系 ........ 很尴尬,但是事实是,很大一部分的程序员不知道协程是啥玩意,更大一部分的程序员,项目中没用 ...
- python基础(16)-进程&线程&协程
进程之multiprocessing模块 Process(进程) Process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建. 介绍 初始化参数 Process([group [, t ...
- (转)python协程2:yield from 从入门到精通
原文:http://blog.gusibi.com/post/python-coroutine-yield-from/ https://mp.weixin.qq.com/s?__biz=MzAwNjI ...
- Python并发编程系列之协程
1 引言 协程是近几年并发编程的一个热门话题,与Python多进程.多线程相比,协程在很多方面优势明显.本文从协程的定义和意义出发,结合asyncio模块详细讲述协程的使用. 2 协程的意义 2.1 ...
- 协程,纤程(Fiber),或者绿色线程(GreenThread)
纤程(Fiber),或者绿色线程(GreenThread) 面试官:你知道协程吗? 你:订机票的那个吗,我常用. 面试官:行,你先回去吧,到时候电话联系 ........ 很尴尬,但是事实是,很大一部 ...
随机推荐
- node使用multer进行文件上传
开场白 在平时的业务中,我们很多使用都会有文件上传这个功能. 今天分享一下使用 node+element-ui实现一下文件上传. 请个人大佬指点一番~~~.批评的时候稍微轻一点. 毕竟我心里承受能力弱 ...
- linux 镜像备份
linux 镜像备份 使用linux虚拟机的方法 优点 镜像大小比较小 缺点 速度可能比较慢 方法 1.打开虚拟机 我用的ubuntu,读卡器连接电脑虚拟机,ubuntu一般会自动挂载 df -h # ...
- cl 编译器环境配置
安装 visual studio 2019 其他版本路径可能有差别,需自行对照查找. visual studio 2019安装目录 和 Windows kits 文件夹[在同一目录下] 即VS 如果安 ...
- Goravel ORM 新增模型关联,用 Golang 写关联也可以跟 Laravel 一样简单
关于 Goravel Goravel 是一个功能完备.具有良好扩展能力的 Web 应用程序框架.作为一个起始脚手架帮助 Golang 开发者快速构建自己的应用.框架风格与 Laravel 保持一致,让 ...
- 灵感宝盒图谱全新改版!代码实验室开启报名丨RTE NG-Lab 双周报
前言 RTE NG-Lab 计划已经推出一段时间了,计划目前包含灵感宝盒(Idea Box).代码实验室(Code Lab).独立开发者孵化器(NGLab Incubator)三个项目.我们希望借助这 ...
- Web自动化——介绍与安装以及第一个web自动化程序(一)
1. 为什么要做Web自动化测试 什么是web自动化测试 让程序代替人,去验证网页上功能的过程 web自动化测试与手工测试的比较 web自动化测试执行的测试用例是手工功能测试的子集 web自动化测试的 ...
- aspnetcore中aop的实现
aaspnetcore开发框架中实现aop不仅仅在业务上,在代码的优雅简洁和架构的稳定上都有着至关重要. 下面介绍三种用过的. 第一种通过System.Reflection的DispatchProxy ...
- Hugging News #0324: 🤖️ 黑客松结果揭晓、一键部署谷歌最新大语言模型、Gradio 新版发布,更新超多!
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- Clion 连接 WSL 编译Unix环境
Clion 连接 WSL 编译Unix环境 安装 WSL Ubuntu 18版本,创建后不要换源,upgrade后安装CMake.g++.gcc 安装 Clion,创建项目 进入setting 在 B ...
- LabVIEW之同步——集合点vi
这是一个对我来讲比较偏的工具,做过很多项目,没有用它也能完成各种各样的项目. 今天我们一起来了解下这个工具,所以称之为工具,因为它属于NI LabVIEW的白色节点,一般是有官方利用LabVIEW代码 ...