随笔 - 569  文章 - 3  评论 - 12617 

 

四:江湖学艺(上)

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

 

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


话说当年,我去游乐乐的时候加上我也才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的实现代码:

 

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,不明觉厉。 

 

posted on 2013-06-16 21:00 路过秋天 阅读(...) 评论(...) 编辑 收藏
路过秋天