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


    四:江湖学艺(上)

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

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


    话说当年,我去游乐乐的时候加上我也才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,不明觉厉。 

  • 相关阅读:
    2、消失的路由,源码的解析基础
    1、v1 与 v2的比较
    uwp 之后台音频
    uwp 之多媒体开发
    UWP 动画之路径
    uwp 动画之圆的放大与缩小
    uwp 中的动画
    C# 输入法
    uwp 之资源的访问
    uwp 之吐司 toast
  • 原文地址:https://www.cnblogs.com/cyq1162/p/3107369.html
Copyright © 2020-2023  润新知