天天看點

DataReader 連結關閉解惑篇

不管是啥xxdatareader,都是繼承datareader實作的,是以是有共性的,是以标題就以datareader為題了。

情況一:datareader 預設連結不關閉

示例代碼:

DataReader 連結關閉解惑篇

static void main(string[] args)

        {

            sqlconnection con = new sqlconnection("server=.;database=myspace;uid=sa;pwd=123456");

            con.open();

            sqlcommand com = new sqlcommand("select top 1 id from blog_user",con);

            sqldatareader sdr = com.executereader(system.data.commandbehavior.closeconnection);

            while (sdr.read())

            {

            }

            console.writeline(sdr.isclosed);

            console.writeline(con.state.tostring());

            console.readline();

        }

DataReader 連結關閉解惑篇

結論是:

false

open

說明:預設無論是不是加system.data.commandbehavior.closeconnection,讀取時資料庫連結不會幫你關閉。

情況二:datareader 連結已關閉

示例代碼:[以下是原文的代碼]

DataReader 連結關閉解惑篇

        protected void bind()

            sqlconnection conn = new sqlconnection(configurationmanager.connectionstrings["constr"].tostring());

            conn.open();

            sqlcommand cmd = new sqlcommand("getalluser", conn);

            sqldatareader sdr = cmd.executereader(commandbehavior.closeconnection);

            repeater1.datasource = sdr;

            repeater1.databind();

            response.write(sdr.isclosed.tostring() + "<br/>");

            response.write(conn.state.tostring());

DataReader 連結關閉解惑篇

結果是:

true

closed

情況:system.data.commandbehavior.closeconnection加完之後,連結給你關閉了,為啥?看下面的分析原因。

三:分析原因

1:從前面的兩個示例上看,差別是什麼?

答:差別就在于一個隻讀資料,另一個綁定了資料清單控件。

2:為什麼綁定了資料清單控件就會自動關閉連結?

答:這就涉及到資料控件綁定機制了,這裡給大夥簡單介紹一下:

b:實作datareader實作此接口的代碼[基類是抽象方法,是以隻能到子類sqldatareader檢視]:

public override ienumerator getenumerator()

{

    return new dbenumerator(this, (this._commandbehavior & commandbehavior.closeconnection) == commandbehavior.closeconnection);

}

從這代碼裡,我們隻看到了它把closeconnection傳進dbenumerator裡了,再進去看一下:

DataReader 連結關閉解惑篇

    public dbenumerator(idatareader reader, bool closereader)

    {

        if (reader == null)

            throw adp.argumentnull("reader");

        this._reader = reader;

        this.closereader = closereader;//此行設定了标志

    }

DataReader 連結關閉解惑篇

點進去隻看到構造函數,并把它賦給this.closereader屬性,因為datareader是向前讀方式,是以重點還是要看其中的一個方法movenext:

DataReader 連結關閉解惑篇

    public bool movenext()

        if (this._schemainfo == null)

            this.buildschemainfo();

        this._current = null;

        if (this._reader.read())//此方法被調用一次,就讀一次

            object[] values = new object[this._schemainfo.length];

            this._reader.getvalues(values);

            this._current = new datarecordinternal(this._schemainfo, values, this._descriptors, this._fieldnamelookup);

            return true;//有資料時直接傳回,不會執行下面的關閉連結

        if (this.closereader)//好,能進行這裡,說明上面讀不到資料,簡說就是資料讀完了

            this._reader.close();//關閉連結操作。

        return false;

DataReader 連結關閉解惑篇

以上代碼就看我注釋的說明。

c:為什麼用datareader綁定清單控件是耍流氓?

答:因為服務端控件清單渲染出表格的周期通常比較長,是以,隻有等到你看到最後結果清單出來的時候,最後一行資料才讀完。

是以連結是持續相當長的處于打開狀态,是以web這種并發多的情況,狂點幾下,估計就報錯了,連結池用滿了。

四:最終結論是什麼?

1:在綁定清單控件時,隻要資料行讀取完畢,就會自動關閉連結。

2:在直接讀取時,不會觸發綁定相關的讀取,是以不會自動關閉連結。

3:在綁定清單控件時,連結長期得不到關閉,并發一來,就挂了,是以大夥就不要耍流氓了。

好了,打完收工,希望對大夥有所幫助。