国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
微軟MVP為您詳述ADO.NET連接池
userphoto

2010.02.25

關注
    本文將為大家介紹的是ADO.NET連接池,這一名詞在ADO.NET中很長見,大家只是采用默認設置,而不知道其具體原理。這里將為大家細細道來。

    對于ADO.NET連接池,大家不會陌生。不過多次用過ADO.NET連接池的各位.NET程序員,卻不一定深入了解它,具體原因是:

    ADO.NET中提供了連接池的功能,多數(shù)開發(fā)人員很少設置它,因為它是默認的。

    界面設置如下圖:

    關閉連接池也很簡單,在連接字符串如下:

    Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=SSPI;Pooling=False;

    但連接池的本質是什么樣的呢?

    用Reflector,打開System.Data.SqlClient.SqlConnection的ConnectionString屬性的設置值的方法,如下:

            
    1. private void ConnectionString_Set(string value)  
    2. {  
    3.     DbConnectionOptions userConnectionOptions = null;  
    4.     DbConnectionPoolGroup group = this.ConnectionFactory.GetConnectionPoolGroup(value, null, ref userConnectionOptions);  
    5.     DbConnectionInternal innerConnection = this.InnerConnection;  
    6.     bool allowSetConnectionString = innerConnection.AllowSetConnectionString;  
    7.     if (allowSetConnectionString)  
    8.     {  
    9.         allowSetConnectionStringthis.SetInnerConnectionFrom(DbConnectionClosedBusy.SingletonInstance, innerConnection);  
    10.         if (allowSetConnectionString)  
    11.         {  
    12.             this._userConnectionOptions = userConnectionOptions;  
    13.             this._poolGroup = group;  
    14.             this._innerConnection = DbConnectionClosedNeverOpened.SingletonInstance;  
    15.         }  
    16.     }  
    17.     if (!allowSetConnectionString)  
    18.     {  
    19.         throw ADP.OpenConnectionPropertySet("ConnectionString", innerConnection.State);  
    20.     }  
    21.     if (Bid.TraceOn)  
    22.     {  
    23.         string str = (userConnectionOptions != null) ? userConnectionOptions.UsersConnectionStringForTrace() : "";  
    24.         Bid.Trace("<prov.DbConnectionHelper.ConnectionString_Set|API> %d#, '%ls'\n", this.ObjectID, str);  
    25.     }  

    再連接 到紅色的GetConnectionPoolGroup方法,如下代碼

            
    1.  internal DbConnectionPoolGroup GetConnectionPoolGroup(string connectionString, DbConnectionPoolGroupOptions poolOptions, 
    2. ref DbConnectionOptions userConnectionOptions)  
    3. {  
    4.     DbConnectionPoolGroup group;  
    5.     if (ADP.IsEmpty(connectionString))  
    6.     {  
    7.         return null;  
    8.     }  
    9.     if (!this._connectionPoolGroups.TryGetValue(connectionString, out group) || (group.IsDisabled && (group.PoolGroupOptions != null)))  
    10.     {  
    11.         DbConnectionOptions options = this.CreateConnectionOptions(connectionString, userConnectionOptions);  
    12.         if (options == null)  
    13.         {  
    14.             throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing);  
    15.         }  
    16.         string str = connectionString;  
    17.         if (userConnectionOptions == null)  
    18.         {  
    19.             userConnectionOptions = options;  
    20.             str = options.Expand();  
    21.             if (str != connectionString)  
    22.             {  
    23.                 return this.GetConnectionPoolGroup(str, null, ref userConnectionOptions);  
    24.             }  
    25.         }  
    26.         if ((poolOptions == null) && ADP.IsWindowsNT)  
    27.         {  
    28.             if (group != null)  
    29.             {  
    30.                 poolOptions = group.PoolGroupOptions;  
    31.             }  
    32.             else  
    33.             {  
    34.                 poolOptions = this.CreateConnectionPoolGroupOptions(options);  
    35.             }  
    36.         }  
    37.         DbConnectionPoolGroup group2 = new DbConnectionPoolGroup(options, poolOptions) {  
    38.             ProviderInfo = this.CreateConnectionPoolGroupProviderInfo(options)  
    39.         };  
    40.         lock (this)  
    41.         {  
    42.             Dictionary<string, DbConnectionPoolGroup> dictionary = this._connectionPoolGroups;  
    43.             if (!dictionary.TryGetValue(str, out group))  
    44.             {  
    45. Dictionary<string, DbConnectionPoolGroup> dictionary2 = new Dictionary<string, DbConnectionPoolGroup>(1 + dictionary.Count);  
    46.                 foreach (KeyValuePair<string, DbConnectionPoolGroup> pair in dictionary)  
    47.                 {  
    48.                     dictionary2.Add(pair.Key, pair.Value);  
    49.                 }  
    50.       dictionary2.Add(str, group2);            this.PerformanceCounters.NumberOfActiveConnectionPoolGroups.Increment();  
    51.                 group = group2;  
    52.                this._connectionPoolGroups = dictionary2;  
    53.             }  
    54.             return group;  
    55.         }  
    56.     }  
    57.     if (userConnectionOptions == null)  
    58.     {  
    59.         userConnectionOptions = group.ConnectionOptions;  
    60.     }  
    61.     return group;  

    TryGetValue是判斷是否存在連接字符串為connectionString的連接,存在返回到group,不存在就調(diào)用CreateConnectionOptions創(chuàng)建一個DbConnectionOptions,最后用

            
    1. lock (this)  
    2.         {  
    3.             Dictionary<string, DbConnectionPoolGroup> dictionary = this._connectionPoolGroups;  
    4.             if (!dictionary.TryGetValue(str, out group))  
    5.             {  
    6. Dictionary<string, DbConnectionPoolGroup> dictionary2 = new Dictionary<string, DbConnectionPoolGroup>(1 + dictionary.Count);  
    7.                 foreach (KeyValuePair<string, DbConnectionPoolGroup> pair in dictionary)  
    8.                 {  
    9.                     dictionary2.Add(pair.Key, pair.Value);  
    10.                 }  
    11.    dictionary2.Add(str, group2);              this.PerformanceCounters.NumberOfActiveConnectionPoolGroups.Increment();  
    12.                 group = group2;  
    13.                 this._connectionPoolGroups = dictionary2;  
    14.             }  
    15.             return group;  
    16.         } 

    這段代碼放到連接池中,在這里,可能顯示的看到,ado.NET的連接池實質上是一個Dictionary<string, DbConnectionPoolGroup>泛型集合。

    所謂的連接池,就是一個與連接對象Connection相關的集合,這不只是簡單的集合,而是有一定的機制在內(nèi)部。我們做開發(fā)時,可能建立Connection連接對象,關閉連接對象,有時候還調(diào)用Dispose來釋放連接。下次再用時,便重新實例化一個連接。但在池中的連接不隨連接對象的Close或Dispose而釋放。如果下次重新建立連接,連接字符串與前一次完全一模一樣,則連接池就會把上次可用的連接對象賦給連接去用。如果兩個連接字符串有一點不一樣,即使在某一個地方多一個空格,連接池也不會以為是相同的連接,這點微軟可能在內(nèi)部只直接去比較兩個字符串了,而不是比較連接數(shù)據(jù)庫字符串的鍵值互相匹配。

    連接池的好處就是保留連接對象,防止下次重頭再來實例化一個連接對象。

            
    1. string constr1 = "Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=SSPI;";  
    2. string constr2 = "Data Source=(local);Initial Catalog=Pubs;Integrated Security=SSPI;";  
    3. string AssMark = "System.Data,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";  
    4. Assembly ass = Assembly.Load(AssMark);  
    5. Type SqlConType = null;  
    6. foreach (Type conType in ass.GetExportedTypes())  
    7. {  
    8.     Console.WriteLine(conType .ToString ());  
    9.     if ("System.Data.SqlClient.SqlConnection" == conType.ToString())  
    10.     {  
    11.         SqlConType = conType;  
    12.     }  
    13. }  
    14. if (SqlConType != null)  
    15. {  
    16.     Type[] types1 = new Type[0];  
    17.     ConstructorInfo constructorInfoObj1 = SqlConType.GetConstructor(  
    18.          BindingFlags.Instance | BindingFlags.Public, null,  
    19.          CallingConventions.HasThis, types1, null);  
    20.     SqlConnection con1 = (SqlConnection)constructorInfoObj1.Invoke(null);  
    21.     con1.ConnectionString = constr1;             
    22.     SqlConnection con2 = (SqlConnection)constructorInfoObj1.Invoke(null);  
    23.     con2.ConnectionString = constr2;   
    24.     PropertyInfo PI = SqlConType.GetProperty("PoolGroup", BindingFlags.Instance | BindingFlags.NonPublic);  
    25.     object poolGroup1 = PI.GetValue(con1, null);  
    26.     object poolGroup2 = PI.GetValue(con2, null);   

    (說明:可能找到結果后覺得非常簡單,但怎么找到結果的,卻是費了很大勁,幾乎是5個小時,所以相把找到結果的過程簡單說一下:

    一開始用Reflector發(fā)現(xiàn)SqlConnection中有一個PoolGroup的屬性,于是就想在運行時候比較兩個SqlConnection對象的這個屬性,但由于這個屬性是的訪問修飾符是internal的,不能直接訪問,只有用反射,代碼(是經(jīng)過優(yōu)化的)如下:

    然后在倒數(shù)第一行設置斷點,為比較poolGroup1和poolGroup2的不同,結果發(fā)現(xiàn),當連接字符串一樣時,這兩個對象的_objectID相同,字符串有一點不同就會不同,這點說明連接池中是用字符串本身比較的,而不是字符串中鍵值對進行比較。同還發(fā)現(xiàn)當con1和con2的ConnectionString不賦值時這兩個對象都是null,由此說明關鍵是ConnectionString賦值上,所以才開始用Reflector查看這個屬性的賦值方法,才有上面的代碼。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ADO.NET遠程訪問Access數(shù)據(jù)庫的連接字符串
ado.net關于操作數(shù)據(jù)庫的連接字符串整理
SubSonic 3.0新特性
Python | JSON數(shù)據(jù)對象處理
ADO Open 方法
Entity Framework與ADO.NET批量插入數(shù)據(jù)性能測試
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服