概述C#代码协同执行

开发 后端
本文介绍C#代码协同执行,以及介绍foreach 的循环体和 GetEnumerator 函数体实际上是在同一个线程中交替执行的。

C#代码协同执行的支持机制

几个月前我曾大致分析过 C# 2.0 中 iterator block 机制的实现原理,《C# 2.0 中Iterators的改进与实现原理浅析》,文中简要介绍了 C# 2.0 是如何在不修改 CLR 的前提下由编译器,通过有限状态机来实现 iterator block 中 yield 关键字。实际上,这一机制的最终目的是提供一个C#代码协同执行的支持机制。

  1. using System.Collections.Generic;  
  2.  
  3. public class Tokens : IEnumerable<string> 
  4. {  
  5. public IEnumerator<string> GetEnumerator()  
  6. {  
  7. for(int i = 0; i<elements.Length; i++)  
  8. yield elements[i];  
  9. }  
  10.  
  11. }  
  12.  
  13. foreach (string item in new Tokens())  
  14. {  
  15. Console.WriteLine(item);  
  16. }  

在这段代码执行过程中,foreach 的循环体和 GetEnumerator 函数体实际上是在同一个线程中交替执行的。这是一种介于线程和顺序执行之间的协同执行模式,之所以称之为协同(Coroutine),是因为同时执行的多个代码块之间的调度是由逻辑隐式协同完成的。顺序执行无所谓并行性,而线程往往是由系统调度程序强制性抢先切换,相对来说Win3.x 中的独占式多任务倒是与协同模型比较类似。
就协同执行而言,从功能上可以分为行为、控制两部分,控制又可进一步细分为控制逻辑和控制状态。行为对应着如何处理目标对象,如上述代码中:行为就是将目标对象打印到控制台;控制则是如何遍历这个 elements 数组,可进一步细分为控制逻辑(顺序遍历)和控制状态(当前遍历到哪个元素)。下面将按照这个逻辑介绍不同语言中如何实现和模拟这些逻辑。

以 Ruby 语言(语法类似 Python)介绍了 Iterator 机制是如何简化遍历操作的代码。实际上中心思想就是将行为与控制分离,由语言层面的支持来降低控制代码的薄记工作。

  1. deftextfiles(dir)  
  2. Dir.chdir(dir)  
  3.  
  4. Dir["*"].eachdo|entry|  
  5. yielddir+"\"+entryif/^.*.txt$/=~entry  
  6.  
  7. ifFileTest.directory?(entry)  
  8. textfiles(entry){|file|yielddir+"\"+file}  
  9. end  
  10. end  
  11. Dir.chdir("..")  
  12. end  
  13.  
  14. textfiles(“c:\”){|file|  
  15. putsfile  

例如上面这段 Ruby 的递归目录处理代码中,就采用了与 C# 2.0 中完全类似的语法实现协同执行支持。

对 C# 1.0 和 C++ 这类不支持协同执行的语言,协同执行过程中的状态迁移或者说执行绪的调度工作,需要由库和使用者自行实现,例如 STL 中的迭代器 (iterator) 自身必须保存了与遍历容器相关的位置信息。例如在 STL 中实现协同执行:

  1. #include<vector> 
  2. #include<algorithm> 
  3. #include<iostream> 
  4.  
  5. //ThefunctionobjectmultipliesanelementbyaFactor  
  6. template<classType> 
  7. classMultValue  
  8. {  
  9. private:  
  10. TypeFactor;//Thevaluetomultiplyby  
  11. public:  
  12. //Constructorinitializesthevaluetomultiplyby  
  13. MultValue(constType&_Val):Factor(_Val){  
  14. }  
  15.  
  16. //Thefunctioncallfortheelementtobemultiplied  
  17. voidoperator()(Type&elem)const  
  18. {  
  19. elem*=Factor;  
  20. }  
  21. };  
  22.  
  23. intmain()  
  24. {  
  25. usingnamespacestd;  
  26.  
  27. vector<int>v1;  
  28.  
  29. //  
  30.  
  31. //Usingfor_eachtomultiplyeachelementbyaFactor  
  32. for_each(v1.begin(),v1.end(),MultValue<int>(-2));  

虽然 STL 较为成功的通过迭代器、算法和谓词,将此协同执行逻辑中的行为和控制分离,谓词表现行为(MultValue<int>、迭代器(v1.being(), v1.end())表现控制状态、算法表现控制逻辑(for_each),但仍然存在编写复杂,使用麻烦,并且语义不连冠的问题。以上介绍C#代码协同执行的支持机制。

【编辑推荐】

  1. 分析C#不安全代码
  2. 浅析C#调用ImageAnimator
  3. C#连接Access、SQL Server数据库
  4. 浅谈C#固定的和活动的变量
  5. 介绍C#中的值类型
责任编辑:佚名 来源: 博客园
相关推荐

2009-08-17 10:54:53

C#执行ping命令

2009-08-14 16:54:19

C# Hello Wo

2009-08-25 12:50:32

数据库常用C#代码

2009-08-06 16:30:58

C#代码和验证码图片

2009-08-31 09:44:23

C# Employee

2009-08-13 15:18:23

C#文件上传

2009-08-18 09:26:07

C#线程功能

2009-07-31 14:08:54

C# 匿名函数

2009-08-18 17:29:02

C#使用指针

2009-09-03 11:15:38

C#设置Coopera

2009-08-20 16:28:45

C#匿名方法

2009-08-25 10:08:39

C# MyData对象

2009-08-25 16:49:44

C#使用if语句

2009-08-24 18:09:13

C#构造函数

2009-08-17 09:57:00

C# Windows

2009-09-03 10:42:16

C# Employee

2009-08-19 11:09:00

C# Cast<T>

2009-09-04 14:41:09

C#同步线程

2009-07-31 15:37:45

C#静态构造函数

2009-08-10 17:12:54

C#编译器
点赞
收藏

51CTO技术栈公众号