yield

【5min+】帮我排个队,谢谢。await Task.Yield()

家住魔仙堡 提交于 2020-01-24 16:11:30
系列介绍 【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net知识等等。 5min+不是超过5分钟的意思,"+"是知识的增加。so,它是让您花费5分钟以下的时间来提升您的知识储备量。 正文 如果您现在正在使用.NetCore的话,相信您对 await 和 async 这两个关键字再熟悉不过了。它们是为异步编程提供的语法糖,便于我们在代码中更便捷的进行异步操作。 await 和 async 其实是对Task对象都一层包装操作。而当我们查看Task对象的时候,会发现他有一个叫做 Yield() 的方法。它的签名是这样: public static YieldAwaitable Yield(); 对于Yield这个单词,可能一下就会让我们联想到C# 里面的关键字 yield return 和yield break。那么这个Task.Yield()究竟是什么作用呢?它会和我们C#里面都关键字一样吗? 而且您会在某些框架或者代码中看到:一旦使用它的话前面都会加上await关键字。这样就写成了 await Task.Yield() 。那么这种写法到底有什么意义呢?我们又该怎么在实际项目中应用呢? 好吧,接下来我们就来对它进行解密。 不过!不过!不过!

协程(迭代器,生成器等)

我的未来我决定 提交于 2020-01-21 17:30:52
一、 补充知识 isinstance(a,A) True 以上如果返回值为True则表示a是A的一个子类 Iterable是一个类,这个类的子类都是可迭代对象 由上图可以知 列表是可迭代对象 问题来了:是否可以通过自己创建的类产生的对象判断ta可以迭代呢? 发现不可以 如果想让类创建的实例对象用for的话,在类中额外添加方法__iter__ 可行但是依旧不可以拿for来循环‘ 因为 普通列表在for循环中取第一个完成后内部自动跳到第二个,但是自己定义的类没有这个光标 因此得在iter 返回一个对象的引用(这个引用必须包含iter和next方法)才可以进行for循环 for temp in classmate: pass 当for循坏是否判断可以运行的时候就是判断classmate是否是一个可迭代对象 如何判断其是否是一个可迭代对象呢?只要classmate中由iter的这个类就算可迭代对象 此时调用对象中iter函数来得到return的返回值,只要返回值中既包含iter和next俩方法,此值就算是迭代器 使用迭代器中的next来进行正常可迭代对象的光标下移 因此每调用一次for循环的temp的时候j就会调用next返回给temp 第一行代码iter(classmate)返回迭代器,将迭代器给一个变量 第二行代码将返回True时证明其就是迭代器 上两行代码验证其是否是迭代器

ES6 Generator函数

我是研究僧i 提交于 2020-01-21 15:45:25
Generator函数是es6提供的解决异步编程的方案之一; Generator函数是一个状态机,内部封装了不同状态的数据; <script type="text/javascript"> // generator定义 function后面跟个*号 function* myGenerator(){ console.log('业务逻辑A') let result=yield 'hello' console.log(result) console.log('业务逻辑B') yield 'world' console.log('执行完了') } let mg=myGenerator(); console.log(mg.next()) console.log(mg.next('hehe')) console.log(mg.next()) </script> 每次执行一次next() 指针想下偏移一次,根据yield来作用; console.log(mg.next()) console.log(mg.next()) console.log(mg.next()) next()返回结果   对应的yield值,然后done的话,只有后面还有yield,就是false;遍历完了,就是true;   yield返回值,默认是undefined 假如需要值的话,我们next()方法里传值即可; 来源:

Python 3.x: Test if generator has elements remaining

笑着哭i 提交于 2020-01-20 18:30:47
问题 When I use a generator in a for loop, it seems to "know", when there are no more elements yielded. Now, I have to use a generator WITHOUT a for loop, and use next () by hand, to get the next element. My problem is, how do I know, if there are no more elements? I know only: next () raises an exception (StopIteration), if there is nothing left, BUT isn't an exception a little bit too "heavy" for such a simple problem? Isn't there a method like has_next () or so? The following lines should make

Python-协程

风格不统一 提交于 2020-01-20 04:14:24
一、引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质: 切换+保存状态 。 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制): 一种情况是该任务发生了阻塞; 另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它。 协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 需要 注意 的是: 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled 可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send 可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 通过yield实现

Python函数进阶:闭包、装饰器、生成器、协程

南楼画角 提交于 2020-01-19 13:21:34
/*--> */ /*--> */ 返回目录 本篇索引 (1) 闭包 (2) 装饰器 (3) 生成器 (4) 协程 (1)闭包 闭包(closure)是很多现代编程语言都有的特点,像C++、Java、JavaScript等都实现或部分实现了闭包功能,很多高级应用都会依靠闭包实现。 一般专业文献上对闭包的定义都比较拗口,比如:“将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象称为闭包。” 其实,简单来说,你可以将闭包看成是一个轻载的类,这个类只有一个函数方法,并且只有为数不多的几个成员变量。 闭包的优点是:实现起来比类稍微轻巧一点(意思就是可以少敲一些代码),并且运行速度比类要快得多(据说约快50%)。下面是一个定义闭包的简单例子: def foo(x, y): def hellofun(): print('hellofun x is %d, y is %d.' %(x,y)) return hellofun a = foo(1,2) b = foo(30,40) a() b() # 运行结果为: hellofun x is 1, y is 2. hellofun x is 30, y is 40. 上例中,foo就定义了一个闭包,它将内部定义的函数hellofun返回(但并不运行这个函数), 同时将入参x,y作为以后hellofun要运行时的环境

深入理解Python中的yield和send

烈酒焚心 提交于 2020-01-19 12:17:39
send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。 但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。 因为当send方法的参数为None时,它与next方法完全等价。但是注意,虽然这样的代码可以接受,但是不规范。所以,在调用send方法之前,还是先调用一次next方法为好。 python特性(八):生成器对象的send方法 - CSDN博客 彻底理解Python中的yield - 简书 Python学习-yield浅析和send()函数 - CSDN博客 Python yield与实现 - cococo点点 - 博客园 yield与send实现协程操作 - 看雪。 - 博客园 转自: https://www.cnblogs.com/wushuaishuai/p/9212812.html 来源: CSDN 作者: yi好快的刀 链接: https://blog.csdn.net/weixin_39461487/article/details/104038635

C#8.0: 在 LINQ 中支持异步的 IAsyncEnumerable

冷暖自知 提交于 2020-01-19 08:00:05
C# 8.0中,提供了一种新的 IAsyncEnumerable<T> 接口,在对集合进行迭代时,支持异步操作。比如在读取文本中的多行字符串时,如果读取每行字符串的时候使用同步方法,那么会导致线程堵塞。 IAsyncEnumerable<T> 可以解决这种情况,在迭代的时候支持使用异步方法。也就是说,之前我们使用 foreach 来对 IEnumerable 进行迭代,现在可以使用 await foreach 来对 IAsyncEnumerable<T> 进行迭代,每个项都是可等待的。这种新的接口称为 async-streams ,将会随 .NET Core 3 发布。我们来看一下如何在 LINQ 中实现异步的迭代。 使用常规的 IEnumerable<T> 首先我们创建一个新的 Console 项目,基于 .NET Core 3 : namespace AsyncLinqDemo { class Program { static void Main(string[] args) { Console.WriteLine("Input the file path:"); var file = Console.ReadLine(); var lines = ReadAllLines(file); foreach (var line in lines) { Console

迭代 装饰器 闭包

给你一囗甜甜゛ 提交于 2020-01-18 11:16:28
迭代器: 包含yield表达式的函数是特殊的函数,叫做生成器函数(generator function),被调用时将返回一个迭代器(iterator),调用时可以使用next或send(msg)。它的用法与return相似,区别在于它会记住上次迭代的状态,继续执行。 send(msg)与next()的区别在于send可以传递参数给yield表达式,这时传递的参数会作为yield表达式的值,而yield的参数是返回给调用者的值。初始调用时必须先next()或send(None),否则会报错。 举个例子: 首先生成一个迭代器f,f.next()会使生成器函数执行到yield,生成一个值然后挂起。 然后f.next()或f.send(msg)会在生成器函数内部返回值,执行到下一个yield,生成值后挂起 然后f.next()或f.send(msg)会在生成器函数内部返回值,意图执行到下一个yield,但是后面没有yield了,所以抛出异常。 使用yield可以有效简化代码,并减少空间浪费。 举个简单例子:列表中的每个元素+1 传统写法: Python代码 def addlist(alist): r = [] for i in alist: r.append(i+1) return r 复制代码 yield写法: Python代码 def addlist(alist): for i in

迭代器和生成器

[亡魂溺海] 提交于 2020-01-17 07:57:50
迭代器(iter) 什么是迭代器 迭代器作为容器,可以保存多个数据,迭代器是一个可以记住遍历的位置的对象,当遍历迭代对象 的时候,下一次的获取到的值会接着上次遍历的位置,直到所有的元素被访问完,那么该迭代对象变成空。迭代器只能依次往后遍历,不能逆向操作。 迭代器的两个基本的方法: iter():将序列转化为迭代器对象 next():依次遍历迭代器中的元素 获取迭代器中的元素 不管用那种方式去获取了元素的值,那么这个元素在迭代器中就不存在了 1)获取单个元素:next(迭代器) / 迭代器. next () -> 获取迭代器中的第一个元素 2)遍历: for 变量 in 迭代器: pass iter1 = 'hello' print ( iter1 ) # <str_iterator at 0x1d529ebbe08> print ( type ( iter1 ) ) # str_iterator print ( next ( iter1 ) ) print ( next ( iter1 ) ) print ( next ( iter1 ) ) print ( iter1 . __next__ ( ) ) print ( iter1 . __next__ ( ) ) # StopIteration如果迭代器为空用next获取元素的时候会报错 或者 for item in iter1