偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

微軟MVP為您詳述ADO.NET連接池

開發(fā) 后端
本文將為大家介紹的是ADO.NET連接池,這一名詞在ADO.NET中很長見,大家只是采用默認(rèn)設(shè)置,而不知道其具體原理。這里將為大家細(xì)細(xì)道來。

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

ADO.NET中提供了連接池的功能,多數(shù)開發(fā)人員很少設(shè)置它,因?yàn)樗悄J(rèn)的。

界面設(shè)置如下圖:

ADO.NET連接池

關(guān)閉連接池也很簡單,在連接字符串如下:

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

但連接池的本質(zhì)是什么樣的呢?

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

  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的連接池實(shí)質(zhì)上是一個Dictionary<string, DbConnectionPoolGroup>泛型集合。

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

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

  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);   

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

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

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

作者簡介:

[[8838]]

桂素偉,微軟MVP,51CTO專家堂成員。微軟中文技術(shù)論壇Visual C#、IT職業(yè)規(guī)劃談兩個版塊版主,微軟WebCast講師。

原文標(biāo)題:ado.net連接池

鏈接:http://www.cnblogs.com/axzxs2001/archive/2010/02/25/1673100.html

【編輯推薦】

  1. 詳細(xì)述說ADO超時相關(guān)問題介紹
  2. 漫談ADO.NET連接池相關(guān)注意問題說明
  3. 如何更好的進(jìn)行ADO.NET連接池連接
  4. 剖析ADO.NET連接池優(yōu)缺點(diǎn)
  5. 談?wù)凙DO.NET數(shù)據(jù)庫連接池創(chuàng)建和分配
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2009-11-03 16:51:04

ADO.NET連接池觀

2009-12-23 09:01:15

ADO.NET連接池

2009-11-13 13:11:37

ADO.NET連接池

2009-11-11 14:04:14

ADO.NET連接池

2009-12-23 14:53:28

ADO.NET連接池

2009-11-12 09:25:21

ADO.NET連接池

2010-01-05 10:11:23

ADO.NET連接池

2009-11-03 15:58:22

2009-12-30 16:22:58

ADO.NET連接池

2009-12-23 09:14:52

ADO.NET連接池

2009-07-20 14:03:43

Ado.net連接池

2009-12-24 09:49:02

ADO.Net連接池

2010-01-04 16:18:13

ADO.NET連接池

2009-06-26 14:41:48

ADO.NET

2009-11-03 16:57:34

ADO.NET FAQ

2009-11-12 08:59:18

ADO.NET數(shù)據(jù)庫連

2009-11-03 16:04:29

2009-12-30 16:26:12

ADO.NET連接池

2009-07-21 11:05:49

關(guān)閉ADO.NET連接

2009-12-18 14:20:26

ADO.NET組件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號