WSS中,微軟提供了一整套完成的介面,使開發人員可以通過這些介面對WSS中資料進行讀寫,那麼,在編寫代碼過程中需要注意哪些問題呢?如何解決這些問題?
WSS物件模型包含對象都實現了IDisposable介面,所以必須注意盡量避免在記憶體中保留沒用的對象。實際上,如果沒有及時清除記憶體中沒用的對象,可以能出現一些問題。
比如,WSS應用程式集區經常性回收,應用程式出現堆棧錯誤,系統效能下降等等。那麼如何防止這些問題發生,我們需要在代碼中注意一些事項:
1. 使用Dispose方法來清除沒用的對象
在WSS物件模型中,主要影響效能的類有SPSite類和SPWeb類,建議在使用完這些類後使用Dispose方法清Null 物件。這些記憶體中的對象在長時間沒有使用的情況下,.net記憶體回收機制進行清理,但是,千萬不要太過相信記憶體回收機制,可能在它回收這些對象之前,你的機器已經崩潰。。:funk:
2. 使用using語句
通過using語句,可以在對象不在使用範圍內自動清空,這樣防止忘記調用dispose方法。如:
using(SPSite oSPsite = new SPSite("http://server"))
{
using(SPWeb oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;
}
}
3. 利用try,catch和finally代碼塊防止程式出錯後對象遺留在記憶體中。
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();
}
注意,在使用重新導向後,將不會調用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();
}
4. 除了SPSite和SPWeb兩個對象類以外,要注意的是,當你訪問SPSite.RootWeb和SPWeb.ParentWeb 這兩個屬性後,你需要清除RootWeb產生的對象。例如:
String str;
SPSite oSPSite = new SPSite("http://server");
str = oSPSite.RootWeb.Title;
str = oSPSite.RootWeb.Url;
... additional processing on RootWeb ...
oSPSite.RootWeb.Dispose(); //注意要刪除RootWeb產生的對象
oSPSite.Dispose();
在開發過程中,這些代碼編寫的細節往往會影響整個系統效能,所有在學習開發時就要養成良好的代碼規範。。
moss.net (2008-7-09 15:05:17)接上面內容,我們針對SPSite和SPWeb對象分析哪些方法或屬性會產生對象並討論如何在不需要時清除這些對象。
SPSite對象
通常在調用SPSite物件建構函數後,你需要在使用完後調用Dispose方法來清Null 物件。但是,如果你使用SPControl.GetContextSite來擷取對象那麼你不能使用Dispose來清Null 物件。因為通過這種方式獲得的SPSite或者SPWeb對象會保留一份內部列表資訊,當使用Dispose對象後,可能會產生無法預測的錯誤。實際上,WSS會在頁面結束後清空這些對象。
下面,我們分析一下有關SPSite類的方法和屬性會產生對象以及如何清空這些對象
SPSiteCollection類
1.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();
通過SPSiteCollection [ ] 索引來獲得SPSite,在下面的例子是沒有及時清除沒有的對象的範例。
int j;
SPSite oSPSite;
SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
for (j = 0;j < aSites.Count;j++)
{
oSPSite = aSites[j];
BuildTableRow(oDisplayTable, "Site", oSPSite.Url);
}
oSPGlobalAdmin.Dispose();
這裡,我們建議在迴圈中加入Dispose方法以清空產生的SPSite對象,例:
int j;
SPSite oSPSite;
SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
for(j = 0;j < aSites.Count;j++)
{
oSPSite = aSites[j];
BuildTableRow(oDisplayTable, "Site", oSPSite.Url);
oSPSite.Dispose();
}
oSPGlobalAdmin.Dispose();
2.SPSite.AllWebs屬性
SPSites.AllWebs.Add方法:建立並返回SPWeb對象,在不需要使用該對象後,你應該清除記憶體中的對象,例:
SPWeb oSPWeb;
SPSite oSPSite = SPControl.GetContextSite(Context);
oSPWeb = oSPSite.AllWebs.Add( ... );
... Process the SPWeb info ...
oSPWeb.Dispose();
3.SPSite.AllWebs [ ] 索引操作在每次訪問對象後會返回SPWeb執行個體,下面的例子會產生大量SPWeb對象。
int j;
SPWeb oSPWeb;
SPSite oSPSite = SPControl.GetContextSite(Context);
for(i=0;j < oSPSite.AllWebs.Count; j++)
{
oSPWeb = oSPSite.AllWebs[j];
BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);
}
建議在迴圈中調用Dispose方法清除對象,例:
int j;
SPWeb oSPWeb;
SPSite oSPSite = SPControl.GetContextSite(Context);
for(j = 0;j < oSPSite.AllWebs.Count; j++)
{
oSPWeb = oSPSite.AllWebs[j];
BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);
oSPWeb.Dispose();
}
或者:
int j;
SPWeb oSPWeb;
SPSite oSPSite = SPControl.GetContextSite(Context);
for(j = 0;j < oSPSite.AllWebs.Count; j++)
{
using(oSPWeb = oSPSite.AllWebs[j])
{
BuildTableRow(oDisplayTable, "Web", oSPWeb.Title);
}
}
4.SPSite.OpenWeb 和 SPSite. SelfServiceCreateSite 方法:這兩個方法都會返回SPWeb對象,你應該按照下面例子方式處理SPWeb對象。
SPSite oSPSite = new SPSite("http://Server");
SPWeb oSPWeb = oSPSite.OpenWeb(..);
... additional processing ...
oSPWeb.Dispose();
oSPSite.Dispose();
5.SPSite.LockIssue, SPSite.Owner, and SPSite.SecondaryContact 屬性
由於這3個屬性會產生SPSite.RootWeb引用,所以,清Null 物件方法應該如下:
String str;
SPSite oSPSite = new SPSite("http://server");
str = oSPSite.LockIssue;
oSPSite.RootWeb.Dispose();
oSPSite.Dispose();
6.SPSite.RootWeb 屬性:
在之前提到過RootWeb屬性,在利用RootWeb的屬性後需要使用清空相關對象,例:
String str;
SPSite oSPSite = new SPSite("http://server");
str = oSPSite.RootWeb.Title;
... additional processing ...
oSPSite.RootWeb.Dispose();
oSPSite.Dispose();
SPWeb 對象
1.SPWeb.ParentWeb屬性:第一次調用SPWeb.ParentWeb的時候,它會判斷賦值的成員變數是否是NULL值,如果成員變數為NULL並且上級網站,那麼它自動調用OPERWEB方法產生一個SPWeb對象,下次在訪問時候只是返回儲存在變數中的值。
例:
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();
2.SPWeb.Webs 屬性
SPWeb.Webs.Add 方法:建立並返回SPWeb對象,在不需要使用該對象後,你應該清除記憶體中的對象,例:
SPWeb oSPWeb
SPSite oSPSite = SPControl.GetContextSite(Context);
oSPSWeb = oSPSite.AllWebs.Add( ... );
... Process the SPWeb info ...
oSPWeb.Dispose();
3.SPWeb.Webs[ ] 索引操作和SPSite.Webs相同,在每次訪問對象後會返回SPWeb執行個體,下面的例子會產生大量SPWeb對象。
int j;
SPWeb oSPWeb, oSPWeb2;
SPSite oSPSite = SPControl.GetContextSite(Context);
oSPWeb = oSPSite.OpenWeb();
for(j = 0;j < oSPWeb.Webs.Count;j++)
{
oSPWeb2 = oSPWeb.Webs[j];
BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);
}
建議在迴圈中清除對象。
int j;
SPWeb oSPWeb, oSPWeb2;
SPSite oSPSite = SPControl.GetContextSite(Context);
oSPWeb = oSPSite.OpenWeb();
for(j = 0;j < oSPWeb.Webs.Count;j++)
{
oSPWeb2 = oSPWeb.Webs[j];
BuildTableRow(oDisplayTable, "Web", oSPWeb2.Title);
oSPWeb2.Dispose();
}
oSPWeb.Dispose();
其他需要清除的對象
1.Microsoft.SharePoint.Portal.SiteData.Area.Web 屬性在每次訪問後返回一個新的SPWeb對象。在使用後應該及時清除對象。
例:
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;
}
2.SPControl.GetContextSite和 SPControl.GetContextWeb 方法:在前面有提到,這裡方法返回對象不能通過Dispose來清除,可能會產生不可預期的錯誤。以下做法是錯誤的:
SPSite oSPSite = SPControl.GetContextSite(..);
... additional processing ...
oSPSite.Dispose();
正確的方法應該是:
SPSite oSPSite = SPControl.GetContextSite(..);
SPWeb oSPWeb = oSPSite.OpenWeb(..);
... additional processing ...
oSPWeb.Dispose();
或者:
SPSite oSPSite = SPControl.GetContextSite(..);
using(SPWeb oSPWeb = oSPsite.OpenWeb())
{
... additional processing ...
}
3.WebPartPage.RootWeb 屬性:和SPSite.RootWeb 屬性相同。只有當WebPartPage.IsRootWeb為True時才需要清除對象,例如:
String str;
WebPartPage oWebPartPage = new WebPartPage();
str = oWebPartPage.RootWeb.Title;
... additional processing ...
if(oWebPartPage.Web.IsRootWeb
oWebPartPage.Dispose();
大部分Sharepoint對象都實現IDisposable介面,當你不使用對象時應該清除該對象,避免在記憶體中儲存過多個物件。
文章來源:http://www.winos.cn/viewthread-38689.html