程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 利用迭代器在.NET中實現“超輕量級線程”

利用迭代器在.NET中實現“超輕量級線程”

編輯:.NET實例教程

 經常在Python,lua之類的腳本語言看到 超輕量級線程的概念,動辄上百萬的線程,碩大的線程數量非常的養眼,今天突發奇想,在c#下也來弄個超輕量線程的實現,雖然很簡陋,但是希望能和大家一起來討論討論。

  且不說超輕量級的線程有用無用。其實現原理基本上都是在單線程中來模擬線程的切換,由於沒有線程切換的開銷,所以看著比系統線程要快。在Python中一般通過yield關鍵字來實現。翻遍msdn發現c#也有yield return的關鍵字。yIEld return 用於實現迭代器。什麼是迭代器呢,這是.Net2.0所帶來的特征,如果不清楚請參見

  http://msdn.microsoft.com/zh-cn/library/dscyy5s0(VS.80).ASPx

  其大意是:

  yield 關鍵字用於指定返回的值。到達 yIEld return 語句時,會保存當前位置。下次調用迭代器時將從此位置重新開始執行。

  這段對我們將要實現的功能尤其重要,其實一言蓋之,yield可以把一個方法分成幾段來執行。但是在C#裡有限制,在調用yield的方法的返回值必須是 IEnumerable,其實說白了,其實是編譯器自動把這段方法轉換成了一個迭代器的對象,這樣一段調用其實也就是在編譯的時候就已經被分段了。根據 msdn的原文描述就是:

  迭代器是 C# 2.0 中的新功能。迭代器是方法、get 訪問器或運算符,它使您能夠在類或結構中支持 foreach 迭代,而不必實現整個 IEnumerable 接口。您只需提供一個迭代器,即可遍歷類中的數據結構。當編譯器檢測到迭代器時,它將自動生成 IEnumerable 或 IEnumerable<T> 接口的 Current、MoveNext 和 Dispose 方法。

  要通過yield來模擬線程,我們必須有線程體,由於yIEld的限制,我們就通過迭代器的方法來作為線程體,然後每個線程一個對象,每個對象裡包含一個迭代器對象,然後在一個大循環裡來調用。代碼如下:
1using System;
  2using System.Collections;
  3using System.Collections.Generic;
  4
  5public class MyClass
  6{
  7    public static void RunSnippet()
  8    {
  9        ThreadLite tl=new ThreadLite();
 10        tl.AddActor(T1);
 11        tl.AddActor(T1);
 12        tl.Run();
 13        
 14    }
 15    public static IEnumerable T1(int id){
 16        for(int i=0;i<10;i++){
 17            Console.WriteLine("Thread "+id+" print "+i);
 18            yIEld return id;
 19        }
 20    }
 21    public static IEnumerable T2(int id){
 22        for(int i=0;i<8;i++){
 23            Console.WriteLine("Thread "+id+" print "+i);
 24            yIEld return id;
 25        }
 26    }
 27    
 28    
 29    Helper methods#region Helper methods
 30    
 31    public static void Main()
 32    {
 33        try
 34        {
 35            RunSnippet();
 36        }
 37        catch (Exception e)
 38        {
 39            string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
 40            Console.WriteLine(error);
 41        }
 42        finally
 43        {
 44            Console.Write("Press any key to continue");
 45            Console.ReadKey();
 46        }
 47    }
 48
 49    private static void WL(object text, params object[] args)
 50    {
 51        Console.WriteLine(text.ToString(), args);    
 52    }
 53    
 54    private static void RL()
 55    {
 56        Console.ReadLine();    
 57    }
 58    
 59    private static void Break() 
 60    {
 61        System.Diagnostics.Debugger.Break();
 62    }
 63
 64    #endregion
 65}
 66
 67class ThreadLite{
 68    int currentid = 1;
 69    public delegate IEnumerable ActorHandler(int id);
 70    private List<IEnumerator> ActionList;
 71    public ThreadLite(){
 72        ActionList=n
ew List<IEnumerator>();
 73    }
 74    public void AddActor(ActorHandler actor){
 75        Actor act=new Actor(actor);
 76        act.ID=this.currentid;
 77        ActionList.Add(act.GetEnumerator());
 78        this.currentid++;
 79    }
 80    
 81    public void Run(){
 82        int fc = 0;
 83        while(true){
 84            foreach(IEnumerator IE in ActionList){
 85                if(!IE.MoveNext()){
 86                    fc++;
 87                }
 88            }
 89            if(fc==ActionList.Count){
 90                break;
 91            }
 92        }
 93        
 94    }
 95    
 96    class Actor{
 97        public int ID{
 98            get;
 99            set;
100        }
101
102        ThreadLite.ActorHandler hdl;
103        public Actor(ThreadLite.ActorHandler handler){
104            hdl=handler;
105        }
106        public IEnumerator GetEnumerator(){
107            IEnumerable IEb = hdl(ID);
108            return IEb.GetEnumerator();
109        }
110    }
111    
112}

執行結果如下:

利用迭代器在.NET中實現“超輕量級線程”a

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved