框架设计之菜鸟漫漫江湖路系列 四:江湖学艺(上)

在项目遭遇难题时,技术总监的到来解决了代码中的DataReader关闭问题,并指导作者学习缓存类的编写,期间涉及多种技术概念的学习与实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

四:江湖学艺(上)

创业帮派项目遇难,引入技术总监人物,力挽狂澜;本人敬之并从其学得武艺

 

本节开始,语言就不复古了,转成大众话的记述文,不然怕是得拖十年才能写完。 


话说当年,我去游乐乐的时候加上我也才4个人,美工2名,加我和技术老大,还有BOSS,凑和5个。

 

就在我闭头苦B Coding 时,短短数日, 游乐乐人员招聘速度飞快;
转眼间各部门已不断成立,美工一部门,编辑一部门,策划一部门,技术一部门。

BOSS想法也日复一日不断演变中,项目已超出原有的规划,上线日期也不断往后推延。


最神秘的,当属原活动版块负责人神秘失踪后,才新招一人负责,第一天一起吃过中午饭,第二天发现人又失踪了。

由于技术老大和BOSS有朋友关系,说好帮手数月,大体项目差不多就会离开,所以BOSS引入技术总监人物,负责统管技术部。

同时原来的技术老大,则转到开发Ulolo后台管理系统。


技术总监来的第一件事,就是审核项目代码,并找出了项目里“经常黄页”的原因:DataReader关闭问题。

我曾经写过一篇关于DataReader,可以参考:DataReader不奇怪,该出手时就出手!,此文介绍了DataReader本质上的相关内涵信息。

关于DataReader问题,由于项目里多处是Ctrl+C,Ctrl+V,批量代码生成量产,已经散落在各个页面中。

所以技术总监的想法是重写SQLHelper里的SqlDataReader的返回

通过重写DataReader, 将原来DataReader的数据,快速读取到一个新的容器MDataReader,然后关闭链接再返回。

所以整体项目代码基本不用改动,当年的秋天小白还是按原来的方式编码,继续CTRL+C+V。

 

这是当年的MDataReader的实现代码:

 

ExpandedBlockStart.gif MDataReader 实现
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
namespace UloloDataFramework.Core.Data
{
     public  class MDataReader : System.Data.IDataReader, System.Collections.IEnumerable
    {
         public  static  implicit  operator MDataReader(System.Data.SqlClient.SqlDataReader _SourceDataReader)
        {
            MDataReader mrdr =  new MDataReader();
            mrdr.CreateSelf( ref _SourceDataReader);
            _SourceDataReader.Close();
            _SourceDataReader.Dispose();
             return mrdr;
        }

         // public static implicit operator MDataReader(System.Data.IDataReader _SourceDataReader)
        
// {
        
//     MDataReader mrdr = new MDataReader();
        
//     mrdr.CreateSelf(ref (SqlDataReader)_SourceDataReader);
        
//     _SourceDataReader.Close();
        
//     _SourceDataReader.Dispose();
        
//     return mrdr;
        
// }


         private System.Collections.Specialized.OrderedDictionary[] _MeList;
         private  int _MeListI = - 1;
         private  int _BaseListI =  0;

         private  bool isRead =  false;
         private  int _RecordsAffected = - 1;
         private  int _FieldCount = - 1;

         public MDataReader()
        {
        }
         public MDataReader(System.Data.IDataReader _SourceDataReader)
        {
             // MDataReader mrdr = new MDataReader();
             this.CreateSelf( ref  _SourceDataReader);
            _SourceDataReader.Close();
            _SourceDataReader.Dispose();
             // return mrdr;
        }
         public MDataReader(System.Data.SqlClient.SqlDataReader _SourceDataReader)
        {
             // MDataReader mrdr = new MDataReader();
             this.CreateSelf( ref _SourceDataReader);
            _SourceDataReader.Close();
            _SourceDataReader.Dispose();
             // return mrdr;
        }
         public  void CreateSelf( ref System.Data.SqlClient.SqlDataReader _SourceDataReader)
        {
             do
            {
                 if (_SourceDataReader.HasRows)
                {
                    _MeListI++;
                    System.Array.Resize<System.Collections.Specialized.OrderedDictionary>( ref _MeList, _MeListI +  1);
                    _MeList[_MeListI] =  new System.Collections.Specialized.OrderedDictionary();

                    _FieldCount = _SourceDataReader.FieldCount;
                    _RecordsAffected = _SourceDataReader.RecordsAffected;
                     for ( int j =  0; _SourceDataReader.Read(); j++)
                    {
                        _MeList[_MeListI].Add(j.ToString(),  new ReaderDataItemClass());
                         for ( int i =  0; i < _SourceDataReader.FieldCount; i++)
                        {
                            ((ReaderDataItemClass)_MeList[_MeListI][j.ToString()]).Add(_SourceDataReader.GetName(i), _SourceDataReader[_SourceDataReader.GetName(i)]);
                        }
                    }
                }

            }  while (_SourceDataReader.NextResult());
        }
         public  void CreateSelf( ref System.Data.IDataReader _SourceDataReader)
        {
            System.Data.SqlClient.SqlDataReader srd = (System.Data.SqlClient.SqlDataReader)_SourceDataReader;
            CreateSelf( ref srd);
            srd.Close();
            srd.Dispose();
        }
         public  bool NextResult()
        {
            _BaseListI++;
             if (_BaseListI > _MeListI)
            {
                Dispose();
                 return  false;

            }
             else
            {
                _MeList[_BaseListI -  1].Clear();
                _MeList[_BaseListI -  1] =  null;
                isRead =  false;
                 return  true;
            }
        }

         public  bool Read()
        {
             try
            {
                 if (!isRead)
                {
                    isRead =  true;
                     return (_MeList[_BaseListI].Count ==  0) ?  false :  true;
                }


                ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).Clear();
                _MeList[_BaseListI][ 0] =  null;
                _MeList[_BaseListI].RemoveAt( 0);
                 return (_MeList[_BaseListI].Count ==  0) ?  false :  true;
            }
             catch {  return  false; }
        }

         public  object  this[ int index]
        {
             get
            {
                 return ((ReaderDataItemClass)_MeList[_BaseListI][ 0])[index];
            }
        }

         public  object  this[ string key]
        {
             get
            {
                 return ((ReaderDataItemClass)_MeList[_BaseListI][ 0])[key];
            }
        }

         public  bool HasRows
        {
             get
            {
                 return (_MeList[_BaseListI].Count ==  0) ?  false :  true;
            }
        }



         public  void Dispose()
        {
            _MeList =  null;
        }

         public  void Close()
        {
            _MeList =  null;
        }

         #region IDataRecord 成员

         public  int FieldCount
        {
             get {  return _MeList ==  null ?  0 : ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).Count; }
        }

         public  bool GetBoolean( int i)
        {
             return  bool.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  byte GetByte( int i)
        {
             return  byte.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  long GetBytes( int i,  long fieldOffset,  byte[] buffer,  int bufferoffset,  int length)
        {
             return  0;
        }

         public  char GetChar( int i)
        {
             return  char.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  long GetChars( int i,  long fieldoffset,  char[] buffer,  int bufferoffset,  int length)
        {
             return  0;
        }


         public  string GetDataTypeName( int i)
        {
             return (((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].GetType().Name);
        }

         public DateTime GetDateTime( int i)
        {
             return DateTime.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  decimal GetDecimal( int i)
        {
             return  decimal.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  double GetDouble( int i)
        {
             return  double.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public Type GetFieldType( int i)
        {
             return (((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].GetType());
        }

         public  float GetFloat( int i)
        {
             return  float.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public Guid GetGuid( int i)
        {
             return  new Guid((((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString()));
        }

         public  short GetInt16( int i)
        {
             return  short.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  int GetInt32( int i)
        {
             return  int.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  long GetInt64( int i)
        {
             return  long.Parse(((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString());
        }

         public  string GetName( int i)
        {
             return ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).Keys[i].ToString();

        }

         public  int GetOrdinal( string name)
        {
            System.Collections.ArrayList tmpList = ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).Keys;
             return tmpList.IndexOf(name);
        }

         public  string GetString( int i)
        {
             return ((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i].ToString();
        }

         public  object GetValue( int i)
        {
             return ((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i];
        }

         public  int GetValues( object[] values)
        {
             for ( int i =  0; i < values.Length; i++)
            {
                values[i] = ((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i];
            }
             return values.Length;
        }

         public  bool IsDBNull( int i)
        {
             return (TypeCode)((ReaderDataItemClass)_MeList[_BaseListI][ 0])[i] == System.TypeCode.DBNull;
        }

         #endregion



         #region IDataReader 成员


         public  int Depth
        {
             get {  return  0; }
        }

         public DataTable GetSchemaTable()
        {
            DataTable dt =  new DataTable();
             object[] tmpObj =  null;
             for ( int i =  0; i < ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).Count -  1; i++)
            {
                dt.Columns.Add( this.GetName(i));
            }

             while ( this.Read())
            {
                ((ReaderDataItemClass)_MeList[_BaseListI][ 0]).CopyTo(tmpObj,  0);
                dt.Rows.Add(tmpObj);
            }

             return dt;
        }

         public  bool IsClosed
        {
             get {  return  true; }
        }

         public  int RecordsAffected
        {
             get {  return _RecordsAffected; }
        }

         #endregion

         #region IDataRecord 成员


         public IDataReader GetData( int i)
        {
             throw  new Exception( " ERR ");
        }

         #endregion

         #region IEnumerable 成员

         public IEnumerator GetEnumerator()
        {
             return  new System.Data.Common.DbEnumerator( this);
        }

         #endregion
    }

     class ReaderDataItemClass : System.Collections.Specialized.OrderedDictionary, System.Collections.Specialized.IOrderedDictionary
    {
         private System.Collections.ArrayList _KeyList;
         public ReaderDataItemClass()
            :  base()
        {
            _KeyList =  new System.Collections.ArrayList();
        }



         public  new System.Collections.ArrayList Keys
        {
             get {  return _KeyList; }
        }



         public  new  void Add( object key,  object value)
        {
            _KeyList.Add(key);
             base.Add(key, value);
        }

         public  new  void Clear()
        {
            _KeyList.Clear();
             base.Clear();
        }


         public  void Remove( int index)
        {
            _KeyList.RemoveAt(index);

             base.RemoveAt(index);
        }

    }

 


当年我是小白,连SQLHelper看着都吃力,连存储过程的编写,也是扔给技术老大的,所以对技术总监的实力就很崇拜了。 

后来招了一个“副技术总监”,负责了原来的活动模块和新开发论坛模块,还有论坛的编辑器。

当我原有项目基本落定时,前后又完成了几个小项目,犹记得刚完成了“目地的指南”模块时,事情就发生了。


我稍有点闲空时,技术总监突然让我写一个缓存类:


我苦思N小时,基于对控件的熟悉程度,我知道页面有这东东可以设置缓存:

然而写成缓存类,那会小白的我,除了会写个实体类,写其它类,咪咪,一时找不着北,蛋疼了近小时。。。


稍会,技术总监和BOSS开完会后出来,问我写的怎样了,我摸了摸头,说了句无从下手。

然后他花了点时间把缓存类的大体写了下,然后让我看懂了再补充。


我看了看,看到一个List<string>,就看不懂了,问技术总监那个List<T>是什么东东。

总监只回答了两个字“泛型”,我没有再问,在网络搜索泛型,看了相关文章和介绍。

同时当年电脑里存档了这样一份CHM知识库文档,在我闲时,总会抽空看看:

 

 

经过多篇文章的学习之后,加上上下左右前中后的扫了多次代码,基本把缓存这块,除了不懂的,能懂的都懂了。

于是一转身,问总监需要加什么功能?

后来大体是要求“缓存优先级别,和界限设置,及按要求定时检测并清空缓存功能”。

基本上前后按总监要求,来回改了N十次,还特别写了个winform界面来测试缓存的稳定性。

2天左右。。一句差不多也算交差了。

 

那会的源码,好在我的硬盘里有存档,这里顺路提供大伙下载,见识下我当年的潜力:点击下载 


那段快速时间,是求知欲最强的时候,和技术总监的交流中,总会遇到一些不明白的词,像“网关”,“VPN”,"DNS“,”Hosts“,"Hook"。

聊的时候我不懂,只能呵呵,总监以为我知道,聊完后回电脑桌边第一件事就是查相关词,了解下是什么东东。

经过不断的搜索,看文章,那时候的智商,看完文章,还是有理解不了词,像”VPN“,”流“,”Hook“。


下篇预告:

四:江湖学艺(下):缓存过后,技术总监让我写MDataTable,不明觉厉。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值