编译器生成的异步可枚举对象制造技术

技术编号:25922961 阅读:63 留言:0更新日期:2020-10-13 10:44
生成单个异步可枚举对象,其包含异步地迭代可枚举所需的数据和方法。异步可枚举对象包含用于一次一步遍历可枚举的代码,以及挂起迭代以等待异步操作的完成和在异步操作的完成后恢复迭代所需的操作。分配单个对象来执行所有这些任务减少了执行异步枚举所需的存储器消耗。

【技术实现步骤摘要】
【国外来华专利技术】编译器生成的异步可枚举对象
技术介绍
迭代器设计模式提出了一种用于面向对象的编程语言的方法,以在不暴露数据的结构的情况下对数据的集合或序列进行迭代。该模式将数据的结构(即集合、序列等)与被用来遍历数据的逻辑分离,这在结构是未知的情况下是有益的,例如当通过网络取回数据或按需制造数据时。通过这种方式,开发方(即程序员、用户等)不必跟踪集合中元素的数目、已被遍历的元素的数目以及在遍历期间集合中剩余的元素的数目。相反,迭代器设计模式使用迭代器对象来访问集合的元素。不同的面向对象的编程语言用特定接口来实现迭代器设计模式,该特定接口定义了使用迭代器对象访问和遍历集合的方法。程序可以包括迭代器块,该迭代器块包含一个或多个源代码语句,该迭代器块对诸如数组、列表、字符串等的数据的集合进行迭代。迭代器块可以包括等待语句,该等待语句挂起迭代中的处理,直到异步操作完成。此时,迭代的状态被保存,以在异步操作完成时在恢复点处恢复其执行。每次迭代时的状态数据可以被存储在堆(heap)上的单独的动态分配的对象中,这导致用于动态分配以及在状态数据不再被程序使用时用于回收该对象的垃圾收集过程的巨大成本。此开销可能是相当大的,并且因此会对程序的响应性和性能产生不利影响。
技术实现思路
提供本
技术实现思路
是为了以简化的形式介绍一些概念,这些概念将在下面的具体实施方式中被进一步描述。本
技术实现思路
既不旨在标识所要求保护的主题的关键特征或基本特征,也不旨在被用来限制所要求保护的主题的范围。生成单个异步可枚举(enumerable)对象,其包含异步地迭代可枚举所需的数据和方法。该异步可枚举对象包含用于一次一步遍历可枚举的代码以及挂起迭代以等待异步操作的完成和异步操作的完成后恢复该迭代所需的操作。分配单个对象来执行所有这些任务减少了执行异步枚举所需的存储器消耗。通过阅读以下详细描述和查看相关联的附图,这些以及其他特征和优点将是显而易见的。应当理解,前述的一般描述和以下的详细描述都仅是解释性的,并且不是对所要求保护的各方面的限制。附图说明图1示出了生成用于异步可枚举的异步可枚举对象的示例性系统。图2A至图2B示出了将定义异步可枚举的用户源代码转换为表示异步可枚举的编译器生成的类,以及将定义异步枚举的用户源代码转换为实现异步枚举的编译器生成的代码。图3是示出了用于生成异步可枚举类的编译器和用于实现异步枚举的代码的示例性方法的流程图。图4是示出了用于执行异步枚举的示例性方法的流程图。图5A至图5B示出了用于异步地和同步地移动到迭代的下一状态的示例性方法。图6是示出了第一操作环境的框图。图7是示出了第二操作环境的框图。图8是示出了第三操作环境的框图。具体实施方式概览所公开的主题涉及减少被用来有利于处理异步可枚举的运行时支持和存储器消耗的量的技术。异步可枚举是可以被异步地枚举的数据的集合或序列。异步可枚举的枚举需要在迭代内等待零个或多个异步操作的完成。本文所公开的技术使用单个异步可枚举对象来处理异步可枚举,该异步可枚举对象包含执行异步枚举所需的数据、协议和操作。所公开的主题关于在由.NET框架支持的编程语言(例如,C#、F#、VisualBasic)中实现异步可枚举而被描述。.NET框架是通过一组工具支持面向对象的编程的代码执行环境,这组工具使得能够开发和执行在基于Windows的操作系统中运行的软件程序。然而,应当理解,所公开的主题并不限于该特定实现,并且所公开的技术适用于异步和/或并行编程环境的其他实现。可枚举是可以被迭代地访问的数据的集合或序列,诸如数组、字符串或列表。枚举器(enumerator)是有利于一次一个元素地遍历集合的对象。枚举器允许用户处理可枚举中的每个元素,而无需知道可枚举中的元素的数目和可枚举的结构。枚举器还可以作为指向集合或可枚举的当前元素的游标。下面的代码段表示异步可枚举在每次迭代中,存在await(等待)语句,其在通过yieldreturni返回i的值之前挂起处理一段时间,这段时间由时间延迟Task.Delay(i*1000)定义。上文引用的伪代码行14-22包含循环,该循环迭代每个await和yield语句由变量items定义的次数。await语句导致处理被挂起,直到延迟已完成。迭代或枚举的状态在挂起点被保存,并且迭代在由await语句中定义的异步操作的完成后恢复。为了在挂起点挂起枚举的执行,迭代的状态和恢复点将需要被保存在堆上,直到与await语句相关联的操作的完成。这将导致对象在循环的每次枚举时被动态地分配,从而增加由异步枚举引起的存储器消耗。本文描述的技术通过利用单个异步可枚举对象来减少该开销,该单个异步可枚举对象存储了通过异步可枚举来有利于枚举所需的数据、协议和方法。为了执行await语句,编译器生成执行支持await语句的操作所需的代码,该操作包括在挂起点保存迭代的状态,确定异步操作何时已完成,以及在恢复点恢复迭代的执行。这关于下面的伪代码段被更特别地示出。CountAsync()异步可枚举被以下伪代码消耗:在上面的伪代码中,foreach语句调用了一次CountAsync()。CountAsync()方法返回被枚举的可枚举,并且该循环的主体调用Console.WriteLine(),其被调用由变量items定义的次数。消耗异步可枚举的代码被认为是异步枚举。为了挂起迭代以等待异步操作的完成,本文描述的技术使用了可等待(awaitable)和等待器(awaiter)。可等待是包含方法GetAwaiter()的对象。GetAwaiter()方法设置了等待器来等待异步操作的完成。当等待表达已完成时,等待器提供通知。等待器包含实现OnCompleted方法、GetResult方法和IsCompleted属性的方法,所有这些方法都被用来检查异步操作是否已经完成,以在异步操作完成时将状态机设置为恢复点,并获取与异步操作的完成相关联的结果。在C#中,存在被用来有利于异步地迭代或枚举数据集合的若干接口。接口仅包含方法签名、属性、事件和索引器。实现接口的类或结构必须实现接口的成员。C#中的编译器生成针对被包含在异步可枚举对象中的接口的实现。在一个方面,存在IAsyncEnumerable<T>接口,其暴露作为可以被异步地枚举的集合的可枚举以及被用来枚举异步可枚举的协议。IAsyncEnumerable<T>接口包含GetEnumerator方法,其获取被用来遍历可枚举的特定枚举器或可枚举的迭代。IAsyncEnumerator<T>接口通过暴露Current属性和MoveNextAsync方法来有利于对集合的遍历。Current属性指示集合中在当前枚举器处的元素。MoveNextAsync方法将枚举器推进到集合中的下一元素。对MoveNextAsync方法的第一次调用会使枚举器移动到集合中的第一个元素。当MoveNext本文档来自技高网...

【技术保护点】
1.一种系统,包括:/n被耦合到存储器的至少一个处理器;以及/n编译器,所述编译器/n创建用以执行异步枚举的类,所述类包括异步可枚举和执行所述异步可枚举的枚举所需的操作,所述操作包括在挂起点处挂起迭代的执行以等待异步操作的完成以及在所述异步操作的完成后在恢复点处恢复所述迭代的执行,以及/n产生第一组指令和第二组指令,所述第一组指令针对所述异步可枚举在运行时基于所述类来分配异步可枚举对象,所述第二组指令利用单个所述异步可枚举对象来枚举所述异步可枚举。/n

【技术特征摘要】
【国外来华专利技术】20180228 US 15/908,7471.一种系统,包括:
被耦合到存储器的至少一个处理器;以及
编译器,所述编译器
创建用以执行异步枚举的类,所述类包括异步可枚举和执行所述异步可枚举的枚举所需的操作,所述操作包括在挂起点处挂起迭代的执行以等待异步操作的完成以及在所述异步操作的完成后在恢复点处恢复所述迭代的执行,以及
产生第一组指令和第二组指令,所述第一组指令针对所述异步可枚举在运行时基于所述类来分配异步可枚举对象,所述第二组指令利用单个所述异步可枚举对象来枚举所述异步可枚举。


2.根据权利要求1所述的系统,其中所述类包括获取枚举器以遍历所述异步可枚举的方法。


3.根据权利要求2所述的系统,其中所述类包括在所述异步操作的完成后将所述枚举器移动到迭代的下一状态的方法。


4.根据权利要求1所述的系统,其中所述类包括在所述异步操作完成时提供通知的可等待。


5.根据权利要求1所述的系统,其中所述类包括至少一种方法,所述至少一种方法确定所述异步操作是否已经完成处理,获取与所述异步操作的完成相关联的结果,并且在所述异步操作的完成后在恢复点处恢复处理。


6.根据权利要求1所述的系统,其中所述类包括状态机,所述状态机包括与挂起的迭代相关联的本地数据和所述异步可枚举的可执行指令。


7.根据权利要求1所述的系统,其中所述类包括在所述异步操作完成时有利于继续到恢复点的方法。

...

【专利技术属性】
技术研发人员:S·H·托布M·托格森
申请(专利权)人:微软技术许可有限责任公司
类型:发明
国别省市:美国;US

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1