WSSv3 Technical Articles_最佳實踐:Windows SharePoint Services對象使用Disposable

WSSv3 Technical Articles_最佳實踐:Windows SharePoint Services對象使用Disposable

摘要:學習在Microsoft .NET Framework下使用Windows SharePoint Services對象模型編寫代碼的最佳方法,這樣可以避免在內存中保留不使用的對象。

Scott Harris, Microsoft Corporation

Mike Ammerlaan, Microsoft Corporation

June 2006

Updated: November 2006

 

應用Microsoft Windows SharePoint Services 3.0, Microsoft Windows SharePoint Services 2.0, Microsoft Office SharePoint Server 2007, Microsoft Office SharePoint Portal Server 2003

 

內容

Ø  介紹使用Disposable來釋放Windows SharePoint Services對象

Ø  編碼技巧

Ø  SPSite對象

Ø  SPWeb

Ø  其他需要Disposal對象

Ø 

Ø  其他資

 

介紹使用Disposable來釋放Windows SharePoint Services對象

Microsoft Windows SharePoint Services 3.0對象模型中的對象是爲Windows SharePoint Services數據和配置提供服務的接口。開發人員常常調用Windows SharePoint Services的對象模型讀寫其中存儲的數據。

Windows SharePoint Services對象模型中的對象都實現了IDisposable接口。在使用這些對象的時候要謹慎,避免他們長期的駐留在Microsoft .NET Framework內存中。所以,在使用完這些SharePoint對象後,要明確的釋放掉它們。在廣泛使用SharePoint對象的時候,例如,在SharePoint站點中使用自定義WebPart,如果沒有即時處理那些可以被釋放掉的對象可能會引起以下的問題:

l  Microsoft Windows SharePoint Services的應用程序池頻繁回收,特別是在高峯時期。

l  應用程序崩潰,表現爲調試器需要的資源溢出。

l  Microsoft Internet Information Services(IIS)工作進程佔用大量內存。

l  系統和應用程序的性能低下。

這篇文章提供了處理和釋放SharePoint對象適當操作的一個指南。

 

背景

一些Windows SharePoint Services對象,基本的SPSite ClassSPWeb Class對象,創建爲受管理的對象。儘管如此,這些對象使用不受管理的代碼和內存來完成它們的主要工作。對象中受管理的部分僅佔很小的一部分;不受管理的卻佔很大部分。因爲受管理的小部分內容並不會造成垃圾回收器的壓力,垃圾回收器也不會及時地釋放佔用的內存。對象佔用的大量不受管理的部分佔用的內存會引起之前提到的不正常的情況。在Windows SharePoint Services使應用程序和IDisposable對象一起工作,必須在對象使用完畢後釋放對象。不應該依賴垃圾回收器來釋放它們佔用的內存。

可以使用任何其它的技術來保證對象被回收。在下面的部分將討論這個問題。

 

編碼技巧

 

可以利用一些編碼技巧來確保對象被釋放。這些技術包括在代碼中使用以下內容:

l  Dispose 方法

l  using 子句

l  try, catch, finally

Dispose vs. Close Method Usage

SPWeb對象和SPSite對象的DisposeClose方法功能上一樣。Dispose方法僅是調用了對象的Close方法。我們推薦調用Dispose方法代替調用Close方法,原因有以下幾點:

l  SPWebSPSite對象實現了IDisposable接口,並且標準.NET Framework進程調用Dispose方法來釋放與對象關聯的所有內存資源。

l  將來代碼發佈也可以保證被正確調用,而不會長時間佔用資源。

using Clause

使用Microsoft Visual C#using子句,它實現了IDisposable接口,它可以自動釋放SharePoint對象。

下面的代碼提供了一個例子:

            String str;

 

            using (SPSite oSPsite = new SPSite("http://server"))

            {

                using (SPWeb oSPWeb = oSPSite.OpenWeb())

                {

                    str = oSPWeb.Title;

                    str = oSPWeb.Url;

                }

            }

try/catch/finally Blocks

下面是使用try/catch/finally Blocks的推薦寫法。當使用try塊時,其中很重要的一點就是添加finally塊來確保所有的對象都被適當的釋放掉了。

任何代碼被包含在try{ }catch{ }塊中需要帶有finally塊,用這個來保證對象被釋放。使用SharePoint對象的時候try{ }catch{ }可以存在功能以外的地方。在那些情況下,就需要在方法裏考慮使用try/catch/finally直接將使用的SharePoint對象包進去。

            String str;

            SPSite oSPSite = null;

            SPWeb oSPWeb = null;

 

            try

            {

                oSPSite = new SPSite("http://server");

                oSPWeb = oSPSite.OpenWeb();

 

                str = oSPWeb.Title;

            }

            catch (Exception e)

            {

            }

            finally

            {

                if (oSPWeb != null)

                    oSPWeb.Dispose();

 

                if (oSPSite != null)

                    oSPSite.Dispose();

            }

調用Response.Redirect將不會執行finally塊的內容。因此,在發生任何重定向或跳轉之前,都需要釋放掉對象。例如,代碼裏面必須要進行重定向,可以按照如下方法進行處理:

            String str;

            SPSite oSPSite = null;

            SPWeb oSPWeb = null;

 

            try

            {

                oSPSite = new SPSite("http://server");

                oSPWeb = oSPSite.OpenWeb();

 

                str = oSPWeb.Title;

                if (bDoRedirection)

                {

                    if (oSPWeb != null)

                        oSPWeb.Dispose();

 

                    if (oSPSite != null)

                        oSPSite.Dispose();

 

                    Response.Redirect("newpage.aspx");

                }

            }

            catch (Exception e)

            {

            }

            finally

            {

                if (oSPWeb != null)

                    oSPWeb.Dispose();

 

                if (oSPSite != null)

                    oSPSite.Dispose();

            }

推薦減少長期的對象保持

爲了減少Windows SharePoint Services對象的長期保持,提供以下幾種推薦的編碼方法:

1.如果爲了操作創建了一個新的對象,那麼這個創建的應用程序需要對其進行釋放。

                   第一種方式

            SPSite oSPSite = new SPSite("http://server");

 

             ... additional processing on SPSite ...

 

            oSPSite.Dispose();

                   第二種方式

            using (SPSite oSPSite = new SPSite("http://server"))

            {

               ... additional processing on SPSite ...

            }

2SharePoint對象返回了其他的SPWeb對象(例如:SPSite.OpenWeb)創建的新對象,需要對其進行釋放。

第一種方式:

            String str;

            SPSite oSPSite = new SPSite("http://server");

            SPWeb oSPWeb = oSPSite.OpenWeb();

 

            str = oSPWeb.Title;

            str = oSPWeb.Url;

 

             ... additional processing on SPWeb ...

 

            oSPWeb.Dispose();

            oSPSite.Dispose();

                   第二種方式:

            String str;

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               using(SPWeb oSPWeb = oSPSite.OpenWeb())

               {

                   str = oSPWeb.Title;

                   str = oSPWeb.Url;

 

                   ... additional processing on SPWeb ...

               }

            }

3SPSite.RootWeb屬性SPWeb.ParentWeb屬性創建了新的對象並將他們賦給本地成員變量。每次成功訪問並使用它們都將他們放到一個本地的成員變量中。這樣,可以隨時對他們進行調用,而不需要創建很多對象。儘管如此,還是需要在使用完這些屬性的時候調用Dispose方法釋放它們。在下面的例子中,可以對RootWebParentWeb使用同樣的處理方法。

第一種方法:

            String str;

            SPSite oSPSite = new SPSite("http://server");

 

            str = oSPSite.RootWeb.Title;

            str = oSPSite.RootWeb.Url;

 

             ... additional processing on RootWeb ...

 

            oSPSite.RootWeb.Dispose();

            oSPSite.Dispose();

第二種方法:

            String str;

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               str = oSPSite.RootWeb.Title;

               str = oSPSite.RootWeb.Url;

 

               ... additional processing on RootWeb ...

 

            oSPSite.RootWeb.Dispose();

            }

第三種方法:

            String str;

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               using(SPWeb oRootWeb = oSPSite.RootWeb)

               {

                  str = oRootWeb.Title;

                  str = oRootWeb.Url;

               additional processing on RootWeb

               }

            }

SPSite對象

 

本部分將描述在何種情況下需要對SPSite對象進行Dispose

一般情況下,任何一個應用都會調用SPSite的構造器來創建一個對象,在使用完的時候我們就需要調用SPSite.Dispose方法來釋放資源。如果是從SPControl.GetContextSite獲取到的SPSite對象,調用的應用將不會釋放掉對象佔用的資源。因爲SPWebSPSite對象在這種情況下被保存在了一個內部的列表中,如果釋放了它們,將會引起SharePoint對象模型的一些其他錯誤。內部處理中,會在頁面完成時用Windows SharePoint Services的枚舉來枚舉列表中的所有對象並釋放它們。

SPSiteCollection Class

這一部分將描述在何種情況下需要對使用的SPSiteCollection對象的方法、屬性、操作進行Close

SPSiteCollection.Add Method

SPSiteCollection.Add將創建並返回一個SPSite對象。在使用完這個方法創建的對象後需要對其進行釋放。

第一種方法:

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            SPSite oSPSite = aSites.Add( ... );

 

             ... Process the site info ...

 

            oSPSite.Dispose();

            oSPGlobalAdmin.Dispose();

第二種方法:

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            using(SPSite oSPSite = aSites.Add( ... ))

            {

               ... Process the site info ...

            }

 

            oSPGlobalAdmin.Dispose();

SPSiteCollection[] Index Operator

每次訪問SPSiteCollection[]的其中一個索引的內容就會返回一個SPSite對象。儘管這個SPSite對象被訪問過了,但還是創建出了一個實例。下面的代碼是不適當的釋放方法。

第一種不適當的方法:

            int i;

            SPSite oSPSite;

 

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            for (i = 0; i < aSites.Count; i++)

            {

                oSPSite = aSites[i];

                BuildTableRow(oDisplayTable, "Site", oSPSite.Url);

            }

 

            oSPGlobalAdmin.Dispose();

第二種不適當的方法:

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            foreach (SPSite oSPSite in aSites)

            {

                BuildTableRow(oDisplayTable, "Site", oSPSite.Url);

            }

 

            oSPGlobalAdmin.Dispose();

推薦的方法裏面修正了其中的問題,在每次循環結束之前釋放掉創建的實例。

第一種推薦的方法:

            int i;

            SPSite oSPSite;

 

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            for (i = 0; i < aSites.Count; i++)

            {

                oSPSite = aSites[i];

                BuildTableRow(oDisplayTable, "Site", oSPSite.Url);

                oSPSite.Dispose();

            }

 

            oSPGlobalAdmin.Dispose();

第二種推薦的方法:

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            foreach (SPSite oSPSite in aSites)

            {

                BuildTableRow(oDisplayTable, "Site", oSPSite.Url);

                oSPSite.Dispose();

            }

 

            oSPGlobalAdmin.Dispose();

第三種推薦的方法:

            int i;

 

            SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();

            SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;

 

            for (i = 0; i < aSites.Count; i++)

            {

                using (SPSite oSPSite = aSites[i])

                {

                    BuildTableRow(oDisplayTable, "Site", oSPSite.Url);

                }

            }

 

            oSPGlobalAdmin.Dispose();

SPSite.AllWebs Property (SPWebCollection)

這一部分將描述在何種情況下需要對使用的SPSite.AllWebs屬性中的SPWeb對象的方法、屬性、操作進行Close

SPSites.AllWebs.Add Method

SPSite.AllWebs.Add方法創建並返回一個SPWeb對象。在使用完後需要對這個方法創建出的對象進行釋放。

第一種方法:

            SPWeb oSPWeb;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPWeb = oSPSite.AllWebs.Add( ... );

 

             ... Process the SPWeb info ...

 

            oSPWeb.Dispose();

第二種方法:

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            using(SPWeb oSPWeb = oSPSite.AllWebs.Add( ... ))

            {

               ... Process the SPWeb info ...

            }

注意:

如果SPSite對象是從GetContextSite()方法獲取的,則不需要手工對其進行釋放。

SPSite.AllWebs [ ] Index Operator

每次訪問SPSite.AllWebs []的其中一個索引的內容就會返回一個SPWeb對象。如果這個屬性沒有被關閉,下面的代碼會將創建出來的SPWeb對象留在.NET Framework的垃圾回收器中等待自動回收,這就就不能馬上釋放資源。

第一種不適當的方法:

            int i;

 

            SPWeb oSPWeb;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            for (i = 0; i < oSPSite.AllWebs.Count; i++)

            {

                oSPWeb = oSPSite.AllWebs[i];

                BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);

            }

第二種不適當的方法:

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            foreach (SPWeb oSPWeb in oSPSite.AllWebs)

            {

                BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);

            }

推薦的方法裏面修正了其中的問題,在每次循環結束之前釋放掉創建的實例。

第一種推薦的方法:

            int i;

 

            SPWeb oSPWeb;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            for (i = 0; i < oSPSite.AllWebs.Count; i++)

            {

                oSPWeb = oSPSite.AllWebs[i];

                BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);

                oSPWeb.Dispose();

            }

第二種推薦的方法:

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            foreach (SPWeb oSPWeb in oSPSite.AllWebs)

            {

                BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);

                oSPWeb.Dispose();

            }

第三種推薦的方法:

            int i;

 

            SPWeb oSPWeb;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            for (i = 0; i < oSPSite.AllWebs.Count; i++)

            {

                using (oSPWeb = oSPSite.AllWebs[i])

                {

                    BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);

                }

            }

SPSite.OpenWeb and SPSite. SelfServiceCreateSite Methods

SPSite.OpenWebSPSite. SelfServiceCreateSite方法會創建一個SPWeb對象並返回。在SPSite類中,這個新建的對象並不存儲在SPSite對象中也不會被自動釋放。因此,需要通過以下方法來釋放它們。

第一種方法:

            SPSite oSPSite = new SPSite("http://Server");

            SPWeb oSPWeb = oSPSite.OpenWeb(..);

 

             ... additional processing ...

 

            oSPWeb.Dispose();

            oSPSite.Dispose();

第二種方法:

            using(SPSite oSPSite = new SPSite("http://Server"))

            {

               using(SPWeb oSPWeb = oSPSite.OpenWeb(..))

               {

                  ... additional processing ...

               }

            }

SPSite.LockIssue, SPSite.Owner, and SPSite.SecondaryContact Properties

以下這些屬性引用自頂級站點的數據並使用SPSite.RootWeb屬性。

l  SPSite.LockIssue

l  SPSite.Owner

l  SPSite.SecondaryContact

如果使用了任何其他的屬性,也需要在SPSite.RootWeb屬性上調用Dispose方法。

第一種方法:

            String str;

            SPSite oSPSite = new SPSite("http://server");

 

            str = oSPSite.LockIssue;

 

            oSPSite.RootWeb.Dispose();

            oSPSite.Dispose();

第二種方法:

            String str;

            using (SPSite oSPSite = new SPSite("http://server"))

            {

                str = oSPSite.Owner;

 

                oSPSite.RootWeb.Dispose();

            }

SPSite.RootWeb Property

如果第一次訪問SPSite.RootWeb,這個屬性將判斷這個成員變量的引用是否是一個空值。如果這個值是空值,將會調用SPSite.OpenWeb方法創建一個新的SPWeb對象並將這個對象賦給這個成員變量。下次再訪問SPSite.RootWeb屬性時,就直接將這個值返回。

需要注意,如果使用了SPSite.RootWeb,需要在釋放SPSite之前釋放SPSite.RootWeb

第一種方法:

            String str;

            SPSite oSPSite = new SPSite("http://server");

 

            str = oSPSite.RootWeb.Title;

 

             ... additional processing ...

 

            oSPSite.RootWeb.Dispose();

            oSPSite.Dispose();

第二種方法:

            String str;

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               str = oSPSite.RootWeb.Title;

               ... additional processing ...

 

               oSPSite.RootWeb.Dispose();

            }

第三種方法:

            String str;

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               using(SPWeb oRootWeb = oSPSite.RootWeb)

               {

                  str = oRootWeb.Title;

 

                  ... additional processing ...

               }

            }

SPWeb對象

 

這部分將描述SPWeb對象需要釋放的一些情況。

SPWeb.ParentWeb Property

如果第一次訪問SPSite.ParentWeb,這個屬性將判斷這個成員變量的引用是否是一個空值。如果這個值是空值,將會判斷它的ParentWeb是否存在,如果存在將調用OpenWeb方法來創建出這個對象並存儲在成員變量中,然後返回這個對象。下次再訪問SPSite.ParentWeb屬性時,就直接將這個值返回。

需要注意,如果使用了SPSite.ParentWeb,需要在釋放SPWeb之前釋放SPSite.ParentWeb

第一種方法:

            String str;

            SPSite oSPSite = new SPSite("http://server");

            SPWeb oSPWeb, oSPWebParent;

 

            oSPWeb = oSPSite.OpenWeb();

            oSPWebParent = oSPWeb.ParentWeb;

 

            if (oSPWebParent != null)

            {

               ... additional processing ...

            }

 

            if (oSPWebParent != null)

               oSPWebParent.Dispose();

 

            oSPWeb.Dispose();

            oSPSite.Dispose();

第二種方法:

            String str;

            SPWeb oSPWeb, oSPWebParent;

 

            using(SPSite oSPSite = new SPSite("http://server"))

            {

               using(SPWeb oSPWeb = oSPSite.OpenWeb())

               {

                  oSPWebParent = oSPWeb.ParentWeb;

 

                  if(oSPWebParent != null)

                  {

                     ... additional processing ...

                  }

 

                  If(oSPWebParent != null)

                     oSPWebParent.Dispose();

               }

            }

SPWeb.Webs Property (SPWebCollection)

這一部分將描述在何種情況下需要對使用的SPWeb.Webs屬性中的SPWeb對象的方法、屬性、操作進行Close

SPWeb.Webs.Add

SPWeb.Webs.Add將創建並返回一個SPWeb對象。在使用完這個方法創建的對象後需要對其進行釋放。

第一種方法:

            SPWeb oSPWeb

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPSWeb = oSPSite.AllWebs.Add( ... );

 

             ... Process the SPWeb info ...

 

            oSPWeb.Dispose();

第二種方法:

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            using(SPWeb oSPSWeb = oSPSite.AllWebs.Add( ... ))

            {

               ... Process the SPWeb info ...

            }

注意:

如果SPSite對象是從GetContextSite()方法獲取的,則不需要手工對其進行釋放。

SPWeb.Webs[ ] Index Operator

每次訪問SPWeb.Webs []的其中一個索引的內容就會返回一個SPWeb對象。儘管這個SPWeb對象被訪問過了,但還是創建出了一個實例。下面的代碼是不適當的釋放方法。

第一種不適當的方法:

            int i;

 

            SPWeb oSPWeb, oSPWeb2;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPWeb = oSPSite.OpenWeb();

 

            for (i = 0; i < oSPWeb.Webs.Count; i++)

            {

                oSPWeb2 = oSPWeb.Webs[i];

                BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);

            }

第二種不適當的方法:

            SPWeb oSPWeb, oSPWeb2;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPWeb = oSPSite.OpenWeb();

 

            foreach (SPWeb oSPWeb2 in oSPWebe.Webs)

            {

                BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);

            }

推薦的方法裏面修正了其中的問題,在每次循環結束之前釋放掉創建的實例。

第一種推薦的方法:

            int i;

 

            SPWeb oSPWeb, oSPWeb2;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPWeb = oSPSite.OpenWeb();

 

            for (i = 0; i < oSPWeb.Webs.Count; i++)

            {

                oSPWeb2 = oSPWeb.Webs[i];

                BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);

                oSPWeb2.Dispose();

            }

 

            oSPWeb.Dispose();

第二種推薦的方法:

            SPWeb oSPWeb, oSPWeb2;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            oSPWeb = oSPSite.OpenWeb();

 

            foreach (SPWeb oSPWeb2 in oSPWeb.Webs)

            {

                BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);

                oSPWeb2.Dispose();

            }

 

            oSPWeb.Dispose();

第三種推薦的方法:

            int i;

 

            SPWeb oSPWeb, oSPWeb2;

            SPSite oSPSite = SPControl.GetContextSite(Context);

 

            using (oSPWeb = oSPSite.OpenWeb())

            {

                for (i = 0; i < oSPWeb.Webs.Count; i++)

                {

                    using (oSPWeb2 = oSPWeb.Webs[i])

                    {

                        BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);

                    }

                }

            }

其他需要Disposal的對象

 

這部分將介紹其他SharePoint對象什麼時候需要調用Dispose方法。

Microsoft.SharePoint.Portal.SiteData.Area.Web Property

訪問Area.Web屬性時將返回一個SPWeb對象。每次使用這個對象之後都要調用Dispose來釋放資源。

不適當的寫法:

            String str;

 

            Area oArea = AreaManager.GetArea(PortalContext.Current, new Guid(AreaGiud));

            str = oArea.Web.Title;   // Web is not reclaimed

            str = oArea.Web.Url;   // Web is not reclaimed

第一種適當的寫法:

            String str;

 

            Area oArea = AreaManager.GetArea(PortalContext.Current, new Guid(AreaGiud));

            SPWeb oSPWeb = oArea.Web;

 

            str = oSPweb.Title;

            str = oSPWeb.Url;

             ...

 

            oSPWeb.Dispose();

第二種適當的寫法:

            String str;

 

            Area oArea = AreaManager.GetArea(PortalContext.Current, new Guid(AreaGiud));

            using (SPWeb oSPWeb = oArea.Web)

            {

                str = oSPweb.Title;

                str = oSPWeb.Url;

            }

SPControl.GetContextSite and SPControl.GetContextWeb Methods

如果對象是從SharePoint上下文對象中獲得,應用程序則不需要調用Dispose方法來釋放對象。如果對它們進行釋放,將會引起SharePoint對象模型的異常或操作失敗。它們被存在SPSiteSPWeb的一張內部列表中。在頁面執行完畢後將會對它們一一進行釋放。

但仍需要對一些從以下對象創建出的對象進行釋放,如果是從SPControl.GetContextSite方法獲取到SPSite對象,可以從這個對象打開並獲取到Web站點對象。

不適當的寫法:

            SPSite oSPSite = SPControl.GetContextSite(..);

 

             ... additional processing ...

 

            oSPSite.Dispose();

            // Could cause problems in the SharePoint object model

第一種適當的寫法:

            SPSite oSPSite = SPControl.GetContextSite(..);

            SPWeb oSPWeb = oSPSite.OpenWeb(..);

 

             ... additional processing ...

 

            oSPWeb.Dispose();

第二種適當的寫法:

            SPSite oSPSite = SPControl.GetContextSite(..);

            using(SPWeb oSPWeb = oSPsite.OpenWeb())

            {

               ... additional processing ...

            }

WebPartPage.RootWeb Property

WebPartPage.RootWeb的調用和SPSite.RootWeb類似。判斷這個成員變量的引用是否是一個空值。如果這個值是空值,將調用SPSite.OpenWen方法創建並返回SPWeb對象;新建的SPWeb對象存儲在成員變量中,或者,如果SPWeb是一個頂級站點,將存放到其他的指到WebPartPage.Web的成員變量中。

調用它的應用僅僅在WebPartPage.IsRootWeb返回一個真值時需要釋放WebPartPage.RootWeb屬性。

推薦方法:

            String str;

            WebPartPage oWebPartPage = new WebPartPage();

 

            str = oWebPartPage.RootWeb.Title;

 

             ... additional processing ...

 

            if(oWebPartPage.Web.IsRootWeb)

               oWebPartPage.Dispose();

結論

 

很多SharePoint對象實現了IDisposable接口,所以你必須小心使用SharePoint對象模型來避免將它們駐留在內存中。這篇文章中描述的關於它們Dispose的指南,可以幫助你保證Windows SharePoint Services自定義的可靠性。

致謝

We would like to thank the following people for their input and guidance in creating this document:

l  Keith Richie, Microsoft Corporation

l  Rob Anderson, Microsoft Corporation

l  Steve Sheppard, Microsoft Corporation

l  Chris Gideon, Microsoft Corporation

l  Kelvin Lo, Microsoft Corporation

l  Rashid Aga, Microsoft Corporation

For more information on this and other SharePoint issues, see Keith Richie's blog.

其他資源

 

Microsoft Windows SharePoint Services Developer Center

Microsoft Office Developer Center: SharePoint Server 2007 Developer Portal

Blog: Keith Richie’s Blog

 

原文地址:Best Practices: Using Disposable Windows SharePoint Services Objects

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章