C#多线程网页采集器(Spider)

来源:互联网 发布:张孝祥java面试大全 编辑:程序博客网 时间:2024/05/27 20:05
这是一个C#语言编写的多线程网页自动采集程序。下面展示了主要类的代码。完整代码请点此下载。
转自:http://www.cnblogs.com/closetome/articles/1711764.html
[csharp] view plain copy
  1. /** 
  2. 软件工程过程实践: 
  3. -------------------------------------------- 
  4. 用例->数据模型->描述系统功能的接口->实际编码->测试->交付 
  5. 文字  逻辑设计   顺序图(通讯图)                     定制 
  6. 图    sql实现    类图(接口方法)                     配置 
  7.       c#实现 
  8.  
  9.  
  10.  
  11. 用例UC1: 网页采集 
  12. ---------------------------------------------- 
  13. 范围: WSE应用 
  14. 级别: 用户目标 
  15. 主要参与者: 采集员 
  16. 涉众及其关注点: 
  17.   ——采集员: 希望能够增加,删除监控URL,启动,停止监控URL,指定监控类型,查看监控URL的列表 
  18.   ——站长: 希望采集活动不要影响正常用户访问 
  19. 前置条件: 采集员必须经过确认和认证 
  20. 成功保证(或后置条件): 存储采集数据,确保没有重复的URL 
  21. 主成功场景(或基本流程): 
  22.   1. 采集员增加新的监控URL,设定采集方式(本页,历遍本页,历遍网站),设定采集速度 
  23.   2. 采集员启动采集 
  24.   3. 采集员停止采集(如果有必要) 
  25.   4. 采集员删除某监控URL(如果有必要) 
  26.   5. 采集员浏览监控URL列表(如果有必要) 
  27.  
  28.  
  29.  
  30. PageInfo数据模型 
  31. ---------------------------- 
  32. 标识符        | id 
  33. 创建时间      | createdTime 
  34. 修改时间      | modifiedTime 
  35. 创建人        | createdUser 
  36. 修改人        | modifiedUser 
  37.               | 
  38. 网址          | URL 
  39. 网址128位MD5  | UrlMD5 
  40. IP地址        | IP 
  41. 采集内容      | content 
  42. 页面类型      | type 
  43.               | 
  44.  
  45.  
  46. 采集流程图 
  47. ------------------------------- 
  48.  
  49.  初始化:载入已经采集的UrlMD5 
  50. |-------------------------------------------------------------------------------------------------------| 
  51. |Spider类                                                                                               | 
  52. |         |---------------------------------------------------------------------|    |----------------| | 
  53. |  |--|   |采集通道(线程)                         ------------------------------|--->| 已采集UrlMD5池 | | 
  54. |  |种|   |      |---------|    |--------|    |---|------|     |--------|       |    |----------------| | 
  55. |  |子|---|---|->| URL队列 |--->| 采集器 |--->|   |  |   |---->| 分析器 |---|   |                       | 
  56. |  |队|   |   |  |---------|    |--------|    |------|---|     |--------|   |   |                       | 
  57. |  |列|   |   |                                      |                      |   |                       | 
  58. |  |--|   |   |--------------------------------------|----------------------|   |    |----------------| | 
  59. |    |---<|                                          ---------------------------|--->| 已采集内容队列 | | 
  60. |    |    |---------------------------------------------------------------------|    |--------|-------| | 
  61. |    |                                                                                        |         | 
  62. |    |    |---------|                                                                         |         | 
  63. |    |---<|存储线程 |<------------------------------------------------------------------------|         | 
  64. |    |    |---------|                                                                                   | 
  65. |    |                                                                                                  | 
  66. |    |    |---------|                                                                                   | 
  67. |    |--->|日志线程 |                                                                                   | 
  68. |         |---------|                                                                                   | 
  69. |                                                                                                       | 
  70. |-------------------------------------------------------------------------------------------------------| 
  71.  
  72.  
  73. 类设计 
  74. ------------------------------- 
  75. 控制器类 
  76.   SpiderHandler -- 控制台入口 
  77.  
  78. 采集核心类 
  79.   Spider     核心 
  80.   PageInfo   基础--数据结构 
  81.   Gatherer   基础--网页采集器 
  82.   Analyser   基础--url分析器 
  83.  
  84. 外部接口 
  85.   IStorage   数据存储接口 
  86.   ISpiderUI  用户界面 
  87.   ILogger    日志接口 
  88.  
  89. */  
  90.   
  91. //==================================================================  
  92. //  
  93. //    该软件是一个由C#编写的基于控制台的多线程网页自动采集程序。  
  94. //    又称之为蜘蛛,机器人,爬行器等。  
  95. //  
  96. //    Copyright(C) 2009 themz.cn All rights reserved  
  97. //    author:   xml  
  98. //    email:    191081370@qq.com  
  99. //    blog:     http://programmingcanruinyourlife.themz.cn/  
  100. //    since:    .net2.0  
  101. //    version:  1.0  
  102. //    created:  2009-08-06  
  103. //    modified: 2009-10-10  
  104. //  
  105. //  版权与免责声明:本软件所有权归原作者,用户可自由免费使用于任何非商业环境。  
  106. //                  如果转载本文代码请不要删除这段版权声明。  
  107. //                  如果由于使用本软件而造成自己或他人的任何损失,均与本软件作者无关。  
  108. //                  特此声明!  
  109. //  
  110. //==================================================================  
  111. //    简单使用帮助:  
  112. //         1. 将下面代码保存到一个.cs后缀的文件中  
  113. //         2. 用.net2.0的编译环境编译成一个exe文件后,双击打开  
  114. //         3. 用 addSeeds命令添加采集种子, 例如: addSeeds http://url/  
  115. //         4. 用 start 命令开始采集  
  116. //         5. 反复使用 getContents 命令查看已采集到的内容  
  117. //         6. pause 命令可暂停采集, start 命令继续  
  118. //         7. stop 命令停止采集  
  119. //         8. exit 命令退出本软件  
  120. //  
  121. //  
  122.   
  123. using System;  
  124. using System.Collections.Generic;  
  125. using System.Data;  
  126. using System.Data.Common;  
  127. using System.IO;  
  128. using System.Net;  
  129. using System.Text;  
  130. using System.Text.RegularExpressions;  
  131. using System.Threading;  
  132.   
  133. //using System.Configuration;  
  134. //using System.Diagnostics;  
  135. //[Serializable()]  
  136. namespace My.WSE.Spider  
  137. {  
  138.   #region 线程模式接口  
  139.     /** 
  140.     线程类模式 
  141.  
  142.     接口  参数 
  143.  
  144.     队列  属性 
  145.     线程  属性 
  146.  
  147.     入队  方法 
  148.     出队  方法 
  149.  
  150.     增加/启动  方法 
  151.     暂停       方法 
  152.     停止       方法 
  153.     */  
  154.     public interface IThread  
  155.     {  
  156.         //T Queue{ get; }  
  157.         //List<Thread> Threads{ get; }  
  158.         //  
  159.         //void Enqueue( T t );  
  160.         //T Dequeue();  
  161.   
  162.         Thread AddThread();  
  163.         void RemoveThread();  
  164.         void RequestThreadPause();  
  165.         void RequestThreadPause( bool pauseOrContinue );  
  166.         void RequestThreadStop();  
  167.     }  
  168.   #endregion  
  169.  
  170.   #region  外部接口  
  171.     // 采集接口  
  172.     public interface IGatherer  
  173.     {  
  174.         void Download( ref PageInfo info,string contentType,int timeout );  
  175.         void Download( ref PageInfo info,int timeout );  
  176.     }  
  177.   
  178.     // 存储接口  
  179.     public interface IStorage  
  180.     {  
  181.         List<string> GetIndexeds();                      //取得所有已下载的URL的MD5值  
  182.   
  183.         List<SeedInfo> GetSeeds();  
  184.         int AddSeed( SeedInfo info );  
  185.         void RemoveSeed( SeedInfo info );  
  186.   
  187.         void SaveContents( List<PageInfo> info );        //保存采集到的内容  
  188.     }  
  189.   
  190.     // 日志接口  
  191.     public interface ILogger  
  192.     {  
  193.         void Write( string content );  
  194.         string Read( string filename );  
  195.   
  196.         string ToString( Exception ex );  
  197.     }  
  198.  
  199.   #endregion  
  200.  
  201.   #region 异常类  
  202.     public class ContentTypeException : Exception  
  203.     {  
  204.         public ContentTypeException( string message ) : base( message ){}  
  205.     }  
  206.   
  207.     public class ContentSizeException : Exception  
  208.     {  
  209.         public ContentSizeException( string message ) : base( message ){}  
  210.     }  
  211.   
  212.     public class NotOnlyException : Exception  
  213.     {  
  214.         public NotOnlyException( string message ) : base( message ){}  
  215.     }  
  216.   
  217.     public class KeyHasExistsException : Exception  
  218.     {  
  219.         public KeyHasExistsException( string message ) : base( message ){}  
  220.     }  
  221.   #endregion  
  222.  
  223.   #region PageInfo队列  
  224.     public class PageQueue  
  225.     {  
  226.         // 构造函数1  
  227.         public PageQueue()  
  228.         {  
  229.             _queue = new LinkedList<string>();  
  230.         }  
  231.         // 构造函数2  
  232.         public PageQueue( ref LinkedList<string> queue ) : this()  
  233.         {  
  234.             ifnull != queue ){  
  235.                 _queue = queue;  
  236.             }  
  237.         }  
  238.  
  239.  
  240.       #region 队列方法  
  241.         public int Count  
  242.         {  
  243.             get{  return _queue.Count;  }  
  244.         }  
  245.         public bool Contains( PageInfo info )  
  246.         {  
  247.             return _queue.Contains( info.UrlMD5 );  
  248.         }  
  249.         public void Enqueue( PageInfo info )   //等同于AddLast  
  250.         {  
  251.             AddLast( info );  
  252.         }  
  253.         public PageInfo Dequeue()              //等同于RemoveFirst  
  254.         {  
  255.             return RemoveFirst();  
  256.         }  
  257.   
  258.         public void AddFirst( PageInfo info )  
  259.         {  
  260.             lock( _queue ){  
  261.                 _queue.AddFirst( info.UrlMD5 );  
  262.                 AddData( info );  
  263.                 Monitor.Pulse( _queue );  
  264.             }  
  265.         }  
  266.         public void AddLast( PageInfo info )  
  267.         {  
  268.             lock( _queue ){  
  269.                 _queue.AddLast( info.UrlMD5 );  
  270.                 AddData( info );  
  271.                 Monitor.Pulse( _queue );  
  272.             }  
  273.         }  
  274.         public PageInfo RemoveFirst()  
  275.         {  
  276.             PageInfo info = null;  
  277.             lock( _queue ){  
  278.                 LinkedListNode<string> node = _queue.First;  
  279.                 ifnull == node ){  
  280.                     Monitor.Wait( _queue );  
  281.                     node = _queue.First;  
  282.                 }  
  283.   
  284.                 string key = node.Value;  
  285.                 _queue.RemoveFirst();  
  286.                 info = GetData(key);  
  287.                 RemoveData(key);    // 释放内存中的数据  
  288.             }  
  289.             return info;  
  290.         }  
  291.         public PageInfo RemoveLast()  
  292.         {  
  293.             PageInfo info = null;  
  294.             lock( _queue ){  
  295.                 LinkedListNode<string> node = _queue.First;  
  296.                 ifnull == node ){  
  297.                     Monitor.Wait( _queue );  
  298.                 }  
  299.                 else{  
  300.                     string key = node.Value;  
  301.                     _queue.RemoveFirst();  
  302.                     info = GetData(key);  
  303.                     RemoveData(key);    // 释放内存中的数据  
  304.                 }  
  305.             }  
  306.             return info;  
  307.         }  
  308.         public PageInfo Remove( PageInfo info )  
  309.         {  
  310.             lock( _queue ){  
  311.                 if( _queue.Remove(info.UrlMD5) ){  
  312.                     info = GetData(info.UrlMD5);  
  313.                     RemoveData(info.UrlMD5);    // 释放内存中的数据  
  314.                 }  
  315.                 else{  
  316.                     info = null;  
  317.                 }  
  318.             }  
  319.             return info;  
  320.         }  
  321.   
  322.         public Dictionary<string,PageInfo> ToDictionary()  
  323.         {  
  324.             Dictionary<string,PageInfo> dict = new Dictionary<string,PageInfo>();  
  325.   
  326.             lock( _queue ){  
  327.                 LinkedListNode<string> node = _queue.First;  
  328.                 whilenull != node ){  
  329.                     dict[node.Value] = GetData(node.Value);  
  330.                     node = node.Next;  
  331.                 }  
  332.             }  
  333.             return dict;  
  334.         }  
  335.       #endregion  
  336.  
  337.       #region 词典方法  
  338.         public PageInfo GetData( string key )  
  339.         {  
  340.             lock( _s_pages ){  
  341.                 if( _s_pages.ContainsKey(key) ){  
  342.                     return _s_pages[key];  
  343.                 }else{  
  344.                     _log.Enqueue( string.Format( "wse.spider.cs GetData,Dictionary键{0}没有找到",key) );  
  345.                     return null;  
  346.                 }  
  347.             }  
  348.         }  
  349.         public void AddData( PageInfo info )  
  350.         {  
  351.             lock( _s_pages ){  
  352.                 _s_pages[info.UrlMD5] = info;  
  353.             }  
  354.         }  
  355.         public void RemoveData( string key )  
  356.         {  
  357.             lock( _s_pages ){  
  358.                 if( _s_pages.ContainsKey(key) ){  
  359.                     _s_pages.Remove(key);  
  360.                 }  
  361.             }  
  362.         }  
  363.         public bool ContainsData( PageInfo info )  
  364.         {  
  365.             return _s_pages.ContainsKey(info.UrlMD5);  
  366.         }  
  367.       #endregion  
  368.  
  369.       #region Private Members  
  370.   
  371.         private LinkedList<string> _queue = null;  
  372.         private static Dictionary<string,PageInfo> _s_pages = new Dictionary<string,PageInfo>();  
  373.   
  374.         private EventLogger _log = new EventLogger();  
  375.       #endregion  
  376.     }  
  377.   #endregion  
  378.  
  379.   #region 采集线程类  
  380.     public class PageGatherer : IThread  
  381.     {  
  382.       #region 构造函数  
  383.         // 构造函数1  
  384.         public PageGatherer(){}  
  385.   
  386.         // 构造函数2  
  387.         public PageGatherer( IGatherer gather )  
  388.         {  
  389.             _log = new EventLogger();  
  390.             _store = new PageStorage();  
  391.   
  392.             _gather = gather;  
  393.             _queue = new PageQueue();        // 每个队列可以  
  394.             _threads = new List<Thread>();   // 有多个线程  
  395.   
  396.             _shouldPause = new ManualResetEvent(true);  
  397.             _shouldStop = false;  
  398.         }  
  399.       #endregion  
  400.  
  401.       #region Public Property  
  402.         // 静态成员公开  
  403.         public Dictionary<string,string> IndexedPool  
  404.         {  
  405.             getreturn _s_indexedPool; }  
  406.         }  
  407.         public PageQueue SeedQueue  
  408.         {  
  409.             get{  return _s_seedQueue;  }  
  410.         }  
  411.   
  412.         // 当前采集队列  
  413.         public PageQueue Queue  
  414.         {  
  415.             get{  return _queue;  }  
  416.         }  
  417.         public List<Thread> Threads  
  418.         {  
  419.             get{  return _threads;  }  
  420.         }  
  421.         // 线程总数  
  422.         public int ThreadCount  
  423.         {  
  424.             get{  return _threadCount;  }  
  425.         }  
  426.       #endregion  
  427.  
  428.       #region 线程方法(Thread Method)  
  429.         // 增加线程  
  430.         public Thread AddThread()  
  431.         {  
  432.             Thread t = new Thread( new ThreadStart(ThreadRun) );  
  433.             t.IsBackground = true;  
  434.             t.Start();  
  435.             _threads.Add(t);  
  436.             _threadCount++;  
  437.             return t;  
  438.         }  
  439.         // 减少线程  
  440.         public void RemoveThread()  
  441.         {  
  442.             // 尚未实现  
  443.         }  
  444.         // 请求线程暂停  
  445.         public void RequestThreadPause()  
  446.         {  
  447.   
  448.         }  
  449.         // 请求线程继续  
  450.         public void RequestThreadPause( bool pauseOrContinue )  
  451.         {  
  452.             if( !pauseOrContinue ){  
  453.                 _shouldPause.Set();  
  454.             }else{  
  455.                 _shouldPause.Reset();  
  456.             }  
  457.         }  
  458.         // 请求线程停止  
  459.         public void RequestThreadStop()  
  460.         {  
  461.             _shouldStop = true;  
  462.         }  
  463.       #endregion  
  464.  
  465.       #region Private Methods  
  466.         // 采集线程方法  
  467.         private void ThreadRun()  
  468.         {  
  469.             PageInfo info = null;  
  470.   
  471.             // 循环: URL->下载->存储->分析->|URL->下载....  
  472.             while( !_shouldStop )  
  473.             {  
  474.                 _shouldPause.WaitOne();              // 是否暂停  
  475.                 if( _queue.Count < 1 ){  
  476.                     _queue.Enqueue( _s_seedQueue.Dequeue() );     // 自动取得种子  
  477.                 }  
  478.   
  479.                 info = _queue.Dequeue();  
  480.                 ifnull == info ){  continue;  }  
  481.   
  482.                 //1 下载  
  483.                 string url = info.URL;  
  484.                 try{  
  485.                     _gather.Download(ref info,"text/html",90000);  
  486.                 }  
  487.                 catch( Exception ex ){  
  488.                     _log.Enqueue( info.URL + " " + ex.ToString() );  
  489.                     continue;  
  490.                 }  
  491.   
  492.                 //2 把当前url加入_s_indexedPool  
  493.                 AddIndexed( info.UrlMD5 );  
  494.   
  495.                 //3 保存:加入_dataPool  
  496.                 _store.Queue.Enqueue( info );  
  497.   
  498.                 //4 分析:加入下载队列queue  
  499.                 AnalyzeToQueue( info, ref _queue );  
  500.             }  
  501.         }  
  502.         // 分析出页面中的url,并把它们加进队列中  
  503.         private void AnalyzeToQueue( PageInfo info, ref PageQueue queue )  
  504.         {  
  505.             PageQueue _queue = queue;  
  506.   
  507.             List<string[]> urls = Analyzer.ParseToURLs(info);  
  508.             PageInfo newInfo = null;  
  509.   
  510.             forint i=0,len=urls.Count; i<len; i++ ){  
  511.                 newInfo = new PageInfo( urls[i][0],info.SeedID );  
  512.   
  513.                 if( !_queue.ContainsData(newInfo) && !_s_indexedPool.ContainsKey(newInfo.UrlMD5) ){  
  514.                     newInfo.Title = urls[i][1];  
  515.                     newInfo.Referer = info.URL;  
  516.   
  517.                     _queue.Enqueue( newInfo );  
  518.                 }  
  519.             }  
  520.         }  
  521.         // 加入已采集队列  
  522.         private void AddIndexed( string urlMD5 )  
  523.         {  
  524.             lock( _s_indexedPool ){  
  525.                 if( !_s_indexedPool.ContainsKey(urlMD5) ){  
  526.                     _s_indexedPool.Add( urlMD5, null );  
  527.                 }  
  528.             }  
  529.         }  
  530.       #endregion  
  531.  
  532.       #region Private Members  
  533.         private EventLogger _log = null;  
  534.         private PageStorage  _store = null;  
  535.   
  536.         private IGatherer _gather = null;       // 接口  
  537.         private PageQueue _queue;               // 每个队列可以  
  538.         private List<Thread> _threads;          // 有多个线程  
  539.   
  540.         private ManualResetEvent _shouldPause;  // 暂停  
  541.         private bool _shouldStop;               // 停止  
  542.   
  543.         private static Dictionary<string,string> _s_indexedPool = new Dictionary<string,string>();      // 已采集的URL  
  544.         private static PageQueue _s_seedQueue = new PageQueue();   // 种子队列  
  545.   
  546.         private static int _threadCount = 0;     // 运行的线程的总数  
  547.       #endregion  
  548.     }  
  549.   #endregion  
  550.  
  551.   #region 存储线程类  
  552.     public class PageStorage  : IThread  
  553.     {  
  554.       #region 构造函数  
  555.         // 构造函数1  
  556.         public PageStorage(){}  
  557.   
  558.         // 构造函数2  
  559.         public PageStorage( IStorage store )  
  560.         {  
  561.             _log = new EventLogger();  
  562.   
  563.             _store = store;  
  564.             _shouldStop = false;  
  565.         }  
  566.       #endregion  
  567.  
  568.       #region Public Property  
  569.         // 对列对象  
  570.         public PageQueue Queue  
  571.         {  
  572.             getreturn _s_queue;  }  
  573.         }  
  574.         // 线程对象集合  
  575.         public List<Thread> Threads  
  576.         {  
  577.             getreturn _threads;  }  
  578.         }  
  579.       #endregion  
  580.  
  581.       #region 线程方法(Thread Method)  
  582.         // 增加线程  
  583.         public Thread AddThread()  
  584.         {  
  585.             Thread t = new Thread( new ThreadStart(ThreadRun) );  
  586.             t.IsBackground = true;  
  587.             t.Start();  
  588.             return t;  
  589.         }  
  590.         // 减少线程  
  591.         public void RemoveThread()  
  592.         {  
  593.             // 尚未实现  
  594.         }  
  595.         // 请求线程暂停  
  596.         public void RequestThreadPause()  
  597.         {  
  598.             // 尚未实现  
  599.         }  
  600.         // 请求线程继续  
  601.         public void RequestThreadPause( bool pauseOrContinue )  
  602.         {  
  603.             // 尚未实现  
  604.         }  
  605.         // 请求线程停止  
  606.         public void RequestThreadStop()  
  607.         {  
  608.             _shouldStop = true;  
  609.         }  
  610.       #endregion  
  611.  
  612.       #region Private Methods  
  613.         // 线程方法  
  614.         private void ThreadRun()  
  615.         {  
  616.             ifnull == _store ){ return;  }  
  617.   
  618.             int count = 10;  
  619.             List<PageInfo> infos = null;  
  620.   
  621.             while( !_shouldStop )  
  622.             {  
  623.                 infos = DequeueSome( count );  
  624.                 try{  
  625.                     _store.SaveContents( infos );  
  626.                 }  
  627.                 catch( Exception ex ){  
  628.                     _log.Enqueue( ex.ToString() );  
  629.                 }  
  630.             }  
  631.         }  
  632.         // 队列方法  
  633.         private List<PageInfo> DequeueSome( int count )  
  634.         {  
  635.             List<PageInfo> infos = new List<PageInfo>();  
  636.   
  637.             forint i=0; i<count; i++ )  // 按每10条记录一组进行存储  
  638.             {  
  639.                 infos.Add( _s_queue.Dequeue() );  
  640.             }  
  641.   
  642.             return infos;  
  643.         }  
  644.       #endregion  
  645.  
  646.       #region Private Members  
  647.         private EventLogger _log;    //日志  
  648.   
  649.         private IStorage _store;                              //接口  
  650.         private static PageQueue _s_queue = new PageQueue();  //队列  
  651.         private List<Thread> _threads = new List<Thread>();   //线程  
  652.   
  653.         private bool _shouldStop;  
  654.       #endregion  
  655.     }  
  656.   #endregion  
  657.  
  658.   #region 日志线程类  
  659.     public class EventLogger : IThread  
  660.     {  
  661.         // 构造函数1  
  662.         public EventLogger(){}  
  663.   
  664.         // 构造函数2  
  665.         public EventLogger( ILogger logger )  
  666.         {  
  667.             _logger = logger;  
  668.             _shouldStop = false;  
  669.             _selfCheckInterval = 300000;    // 5分钟  
  670.         }  
  671.       #region Public Properties  
  672.         public Queue<string> Queue  
  673.         {  
  674.             get{  return _s_queue;  }  
  675.         }  
  676.         public List<Thread> Threads  
  677.         {  
  678.             get{  return _threads;  }  
  679.         }  
  680.       #endregion  
  681.  
  682.       #region 队列方法(Queue Method)  
  683.         public void Enqueue( string s )  
  684.         {  
  685.             lock( _s_queue ){  
  686.                 _s_queue.Enqueue( s );  
  687.                 Monitor.Pulse( _s_queue );  
  688.             }  
  689.         }  
  690.         public string Dequeue()  
  691.         {  
  692.             lock( _s_queue )  
  693.             {  
  694.                 if( 1 > _s_queue.Count ){  
  695.                     Monitor.Wait( _s_queue );  
  696.                 }  
  697.                 return _s_queue.Dequeue();  
  698.             }  
  699.         }  
  700.       #endregion  
  701.  
  702.       #region 线程方法(Thread Method)  
  703.         //  
  704.         public Thread AddThread()  
  705.         {  
  706.             Thread t = new Thread( new ThreadStart(ThreadRun) );  
  707.             t.IsBackground = true;  
  708.             t.Start();  
  709.             _threads.Add(t);  
  710.             return t;  
  711.         }  
  712.         // 减少线程  
  713.         public void RemoveThread()  
  714.         {  
  715.             // 尚未实现  
  716.         }  
  717.         // 请求线程暂停  
  718.         public void RequestThreadPause()  
  719.         {  
  720.             // 尚未实现  
  721.         }  
  722.         // 请求线程继续  
  723.         public void RequestThreadPause( bool pauseOrContinue )  
  724.         {  
  725.             // 尚未实现  
  726.         }  
  727.         // 请求线程停止  
  728.         public void RequestThreadStop()  
  729.         {  
  730.             _shouldStop = true;  
  731.         }  
  732.         // 增加自检线程  
  733.         public void AddSelfCheckThread()  
  734.         {  
  735.             iffalse == _isSelfCheckRun ){  
  736.                 Thread t = new Thread( new ThreadStart(SelfCheck) );  
  737.                 t.IsBackground = true;  
  738.                 t.Start();  
  739.                 _isSelfCheckRun = true;  
  740.             }  
  741.         }  
  742.       #endregion  
  743.  
  744.       #region Private Methods  
  745.         // 日志主线程函数  
  746.         private void ThreadRun()  
  747.         {  
  748.             ifnull == _logger ){ return;  }  
  749.   
  750.             while( !_shouldStop )  
  751.             {  
  752.                 try{  
  753.                     _logger.Write( Dequeue() );  
  754.                 }  
  755.                 catch( Exception ex ){  
  756.                     Console.WriteLine( string.Format( "警告:日志写入发生错误{0}",ex.ToString() ) );  
  757.                 }  
  758.             }  
  759.         }  
  760.         // 日志自检子线程函数  
  761.         private void SelfCheck()  
  762.         {  
  763.             ifnull == _logger ){ return;  }  
  764.   
  765.             while( !_shouldStop )  
  766.             {  
  767.                 try{  
  768.                     _logger.Write( "日志自检完成" );  
  769.                     Thread.Sleep( _selfCheckInterval );  
  770.                 }  
  771.                 catch( Exception ex ){  
  772.                     Console.WriteLine( string.Format( "警告:日志自检发生错误{0}",ex.ToString() ) );  
  773.                 }  
  774.             }  
  775.         }  
  776.       #endregion  
  777.  
  778.       #region Private Members  
  779.         private ILogger _logger = null;                               // 接口  
  780.         private static Queue<string> _s_queue = new Queue<string>();  // 一些标志性事件(异常或成功)  
  781.         private List<Thread> _threads = new List<Thread>();           // 一个队列可以有多个线程  
  782.   
  783.         private bool _shouldStop;  
  784.   
  785.         private int _selfCheckInterval;   // 日志模块自检间隔  
  786.         private static bool _isSelfCheckRun = false;  
  787.       #endregion  
  788.     }  
  789.   #endregion  
  790.   
  791. // end namespace My.WSE
0 0
原创粉丝点击