SharePoint性能总结和一些开发经验

来源:互联网 发布:淘宝网恒源祥羊毛衫 编辑:程序博客网 时间:2024/04/28 05:33
1.取得列表中的Item的数量:
Int  count =  SPContext.Current.List.Items.Count;
这句是取得Item的数目,不得不取得列表中的所有的Item的metadata,这样我们程序运行的速度就会相对慢一些,如果列表中的数据量不大,那不会有明显的影响,如果列表中的数据量很大,那在效率上会有很大的影响。
Int  count =  SPContext.Current.List.ItemCount;//建议使用这个来取得列表中的item数量。
 
2.显示列表中的item
SPList  list = SPContext.Current.List;
For(int i=0;i<50;i++)
{
   SPListItem listItem = list.Items[i];
}
这样每次都会请求SPListItemCollection集合的新的对象,而使item集合对象没有被缓存。因此不断的从数据库请求所有的数据项,对性能上造成很大的影响。
建议的方法是:
SPListItemCollection  item = SPContext.Current.List.Items;
For(int i=0;i<50;i++)
{
   SPListItem item = items[i];
}
3.取得item对象
SPListItem item = SPContext.Current.List.Items[0];
这句主要是从list中先取得对象的所有的Item的Metadata,然后再从这些Item的集合中取得到index是0的Item
建议使用下面语句进行取得Item对象:
SPListItem item = SPContext.Current.List.GetItemById(0);
两句SDK执行的区别就是我们使用SQL语句进行查询的时候,第一没有设置where子句的条件,而第二句则是设置了where子句的条件,在数据量很大的情况下,这样第二句执行的速度会远远大于第一句执行的速度。
4.更新大量的SharePoint 列表数据项
For(int itemIndex=0;itemIndex<100;itemIndex++)
{
   SPListItem newItem = items.Add();
   newItem.Update();
}
实际上item的Add 或是Update方法是调用了一个存储过程,来完成这个操作的。
如果需要大量的数据更行的使用建议使用SPWeb的ProcessBatchData方法进行更新。具体实例如下:
SPContext.Current.Web.ProcessBatchData(queryString);
 
5.取得SharePoint的列表对象
SPList list = SPContext.Current.Web.Lists[title];
这句取得列表对象先从站点中取得所有的List的Metadata和title进行比较,找到符合条件的list之后返回。
建议使用下面的方法取得列表对象:
SPList list = SPContext.Current.Web.GetList(listUrl);或

SPList list = SPContext.Current.Web.GetListByUrl(listUrl);



6.SharePoint中常用的自定义Feature的Location和GroupId
位置
自定义操作组 ID
组说明
默认自定义操作 ID
DisplayFormToolbar
N/A
Location 对应于列表的显示表单工具栏。
ExportEventToolbarButton(日历)
ExportContactToolbarButton(联系人)
EditControlBlock
N/A
对应于每项编辑控件块 (ECB) 菜单。
EditFormToolbar
N/A
Location 对应于列表的编辑表单工具栏。
Microsoft.SharePoint.Administration.ApplicationCreated
链接
“已创建应用程序”页。
CreateSite
HomePage
Microsoft.SharePoint.Administration.ApplicationManagement
ApplicationSecurity
管理中心的“应用程序管理”页面上的“应用程序安全性”部分。
..WebPartSecurity
..SelfService
..WebApplicationSecurity
..ManagePolicy
ManageAuthenticationProviders
Microsoft.SharePoint.Administration.ApplicationManagement
ExternalService
..管理中心的“应用程序管理”页面上的“外部服务连接”部分。
..OfficialFile
..HtmlViewer
DocConversion
Microsoft.SharePoint.Administration.ApplicationManagement
SiteManagement
..管理中心的“应用程序管理”页面上的“SharePoint 网站管理”部分。
..CreateSite
..DeleteSite
..SiteUse
..QuotaDefinition
..SiteQuota
..SiteOwners
ListSiteCollections
Microsoft.SharePoint.Administration.ApplicationManagement
WebApplicationConfiguration
..管理中心的“应用程序管理”页面上的“SharePoint Web 应用程序管理”部分。
..Extend
..Unextend
..Delete
..ManagedPaths
..EmailSettings
..GeneralSettings
..ManageContentDatabases
..ManageWebAppFeatures
ListWebApplications
Microsoft.SharePoint.Administration.ApplicationManagement
WorkflowManagement
管理中心的“应用程序管理”页面上的“工作流管理”部分。
WorkflowManagement
Microsoft.SharePoint.Administration.Operations
BackupRestore
管理中心的“操作”页面上的“备份和还原”部分。
..Backup
..BackupHistory
..Restore
BackupStatus
Microsoft.SharePoint.Administration.Operations
DataConfiguration
管理中心的“操作”页面上的“数据配置”部分。
..DefaultDatabase
DataRetrieval
Microsoft.SharePoint.Administration.Operations
GlobalConfiguration
..管理中心的“操作”页面上的“全局配置”部分。
..RunningJobs
..JobDefinitions
..AlternateAccessMappings
..ManageFarmFeatures
Solutions
Microsoft.SharePoint.Administration.Operations
LoggingAndReporting
管理中心的“操作”页面上的“日志记录和报告”部分。
..DiagnosticLogging
UsageAnalysis
Microsoft.SharePoint.Administration.Operations
Security
管理中心的“操作”页面上的“安全性配置”部分。
..ServiceAccount
..Irm
..Antivirus
..BlockedFileTypes
AdministrationRoles
Microsoft.SharePoint.Administration.Operations
Topology
管理中心的“操作”页面上的“拓扑结构和服务”部分。
..FarmServers
..TopologyServices
..IncomingEmailServer
..ApproveDGs
EmailConfiguration
Microsoft.SharePoint.Administration.Operations
Upgrade
管理中心的“操作”页面。
..SiteUpgradeStatus
FinalizeUpgrade
Microsoft.SharePoint.ContentTypeSettings
Fields
..网站集的“内容类型”页面上的“列”部分。
..AddField
..ReorderFields
Microsoft.SharePoint.ContentTypeSettings
General
..网站集的“内容类型”页面上的“设置”部分。
..ChangeNameDescription
..ChangeOptionalSettings
..ChangeWorkflowSettings
..RemoveContentType
Microsoft.SharePoint.ContentTypeTemplateSettings
Fields
..列表的“内容类型”页面上的“列”部分。
..AddField
..ReorderFields
Microsoft.SharePoint.ContentTypeTemplateSettings
General
列表的“内容类型”页面上的“设置”部分。
..ChangeNameDescriptionGroup
..ChangeOptionalSettings
..ChangeWorkflowSettings
RemoveContentType
Microsoft.SharePoint.Create
WebPages
“创建”页面上的“网页”部分。
Microsoft.SharePoint.GroupsPage
NewMenu
网站集的“人员和组”页面上的“新建”菜单。
Microsoft.SharePoint.GroupsPage
SettingsMenu
网站集的“人员和组”页面上的“设置”菜单。
Microsoft.SharePoint.ListEdit
Communications
列表或文档库的“自定义”页面上的“通信”部分。
Microsoft.SharePoint.ListEdit
GeneralSettings
列表的“自定义”页面上的“常规设置”部分。
Microsoft.SharePoint.ListEdit
Permissions
列表或文档库的“自定义”页面上的“权限和管理”部分。
Microsoft.SharePoint.ListEdit.DocumentLibrary
GeneralSettings
文档库的“自定义”页面上的“常规设置”部分。
Microsoft.SharePoint.PeoplePage
ActionsMenu
网站集的“人员和组”页面上的“操作”菜单。
Microsoft.SharePoint.PeoplePage
NewMenu
网站集的“人员和组”页面上的“新建”菜单。
Microsoft.SharePoint.PeoplePage
SettingsMenu
网站集的“人员和组”页面上的“设置”菜单。
Microsoft.SharePoint.SiteSettings
Customization
..“网站设置”页面上的“外观”部分。
..ProjectSettings
..NavOptions
..Theme
..TopNav
..QuickLaunch
..SaveAsTemplate
..ReGhost
Microsoft.SharePoint.SiteSettings
Galleries
..“网站设置”页面上的“库”部分。
..MasterPageCatalog
..ManageCType
..ManageField
..SiteTemplates
..ListTemplates
..WebParts
..Workflows
Microsoft.SharePoint.SiteSettings
SiteAdministration
..“网站设置”页面上的“网站管理”部分。
..RegionalSettings
..LibrariesAndLists
..WebUsage
..UserAlerts
..RSS
..SrchVis
..ManageSubWebs
..ManageSiteFeatures
..DeleteWeb
Microsoft.SharePoint.SiteSettings
SiteCollectionAdmin
..“网站设置”页面上的“网站集管理”部分。
..DeletedItems
..SiteCollectionUsage
..Storage
..ManageSiteCollectionFeatures
..Hierarchy
..Portal
Microsoft.SharePoint.SiteSettings
UsersAndPermissions
..“网站设置”页面上的“用户和权限”部分。
..PeopleAndGroups
..SiteCollectionAdministrators
..User
Microsoft.SharePoint.StandardMenu
ActionsMenu
列表和文档库视图中的“操作”菜单。
Microsoft.SharePoint.StandardMenu
ActionsMenuForSurvey
用于调查的“网站操作”菜单。
Microsoft.SharePoint.StandardMenu
NewMenu
列表和文档库视图中的“新建”菜单。
Microsoft.SharePoint.StandardMenu
SettingsMenu
列表和文档库视图中的“设置”菜单。
Microsoft.SharePoint.StandardMenu
SettingsMenuForSurvey
用于调查的“网站设置”链接。
Microsoft.SharePoint.StandardMenu
SiteActions
“网站操作”菜单。
Microsoft.SharePoint.StandardMenu
UploadMenu
文档库视图中的“上载”菜单。
Microsoft.SharePoint.User
ActionsMenu
网站的“权限”页面上的“操作”菜单。
Microsoft.SharePoint.User
NewMenu
网站的“权限”页面上的“新建”菜单。
Microsoft.SharePoint.User
SettingsMenu
网站的“权限”页面上的“设置”菜单。
Microsoft.SharePoint.Workflows
LeftNavBarLinks
用于管理工作流的页面上的左侧导航区域。
NewFormToolbar
N/A
Location 对应于列表的新建表单工具栏。
ViewToolbar
N/A
Location 对应于列表视图中的工具栏。


7.如果遇到字符串拼接,我们通常使用StringBuilder,而不是直接使用字符串直接的链接
字符串直接的链接需要的内存量很大,效率很低。建议方法如下:
StringBuilder msgString =  new StringBuidler();
xmlString.Append(“message1”);
xmlString.Append(“message1”);
 
string message = msgString.ToString();
不建议使用的方法是:
String message = “message1”+”message2”;
特别是在消息字符串很长的情况下。程序运行的效率相当的低。
8.SharePoint中有一些对象是非托管的对象,所以需要我们手动进行释放,防止内存泄漏。
例如:SPSite,SPWeb等等其他一些对象。但是需要注意的是我们如果使用全局的SPWeb,就不应该进行释放,例如:SPContext.Current.Web就是一个全局的Web对象,当我们使用这个对象的时候,我们不应该把这个对象进行Dispose。
一般的释放非托管对象的方法有两种:
(1)     try ---catch---finally
SPSite site = null;
Try
{
     Site = new SPSite(“http://server:80”);
}
Catch(Exception er)
{
     //TODO:
}
Finally
{
     If(site != null)
{
 Site.Dispose();
}
}
(2)     using
using(SPSite site = new SPSite(“http://server:80”))
{
     //TODO
}
9.字符串的比较操作
在比较的时候我们应该注意是否忽略大小写,这个地方是很容易出现问题的地方。
String  name1 =  “A”;
String  name2 = “a”;
 
Bool flag = name1.Equals(name2);// flag 是false
Bool flag = name1.Equals(name2, StringComparison.OrdinalIgnoreCase);//flag 是true
10.    在SharePoint中我们要设置folder的权限,首先我们要打破原有的继承的权限,但是这里有一个问题需要注意一下:
如果使用folder.Item.BreakRoleInheritance(false)的时候会抛出一个异常,原因是SharePoint API中原有这个问题。我们解决这个问题通常使用folder. Item.BreakRoleInheritance(true);然后我们在删除掉他原有的权限。这样操作之后再给这个folder赋予新的权限即可。
11.    保持程度的可读性
(1) 在程序中最好不要多次使用return , 尽量在程序结束或是我们的逻辑完成的时候进行return例如:
If(testValue == 1)
{
Return 1;
}
Else if(testValue == 2)
{
   Return 2;
}
…….
建议使用如下方法:
Int returnValue =0;
If(testValue ==1)
{
   returnValue = 1;
}
Elseif(testValue ==2)
{
   returnValue = 2;
 
}
……
Return returnValue;
(2) 在程序中尽量不要使用GoTo语句,使用GoTO语句使程序非常的不可读,可能之后编写程序的人才懂程序的意思,其他人根本看不懂程序是完成什么功能的,还有可能时间长了,编写程序的人自己也不懂具体是什么意思了,这样会非常糟糕,不利于以后的扩展和维护。
 
12.    判断字符串是否为空串,应该尽量使用下面方法:
String message = “123”;
Bool flag = string.IsNullOrEmpty(message);
我们在初始化一个空字符串的时候,应该尽量使用如下方法:
String str1 = string.Empty;
尽量不要使用 string str2 = “”;
因为这两种内存分配的方式,是不同的,C#内部处理的机制也是不相同的。
13.    注意C#中的拆箱和装箱问题

在编程实践中我们如果使用List<T> lists = new List<T>();,能够解决的问题,最好不要使用ArrayList和Hashtable等集合,因为ArrayList、Hashtable这样的集合会存在拆箱和装箱问题,占用程序很大的性能,如果数量过多会严重影响性能。


SharePoint2010支持Client端的对象模型中,提供的对象主要包含在Microsoft.SharePoint.Client.dll和Microsoft.SharePoint.Client.Runtime.dll中。

在SharePoint Client端对象模型中,主要是ClientContext对象,这个对象是访问Client Object 的入口,例如:使用Client端对象模型在服务器端创建一个列表代码如下:

需要引用下面的命名空间

Using ClientCOM = Microsoft.SharePoint.Client;

Using Microsoft.SharePoint.Client;

 

ClientContext clientContext = new ClientContext(siteUrl);

Web webSite = clientContext.Web;

ListCreationInformation listInfo = new ListCreationInformation();

listInfo.Title = “My Links”;

listInfo.TemplateType  =(int)ListTemplateType.Links;

List newList = webSite.Lists.Add(listInfo);

clientContext.ExecuteQuery();

这里需要注意的是,提交任何操作需要调用clientContext.ExecuteQuery();

来完成,这里Client端对象模型,可以完成Server端对象模型的常用操作。

 

在SharePoint2010中,将Linq集成进去,并且支持的非常好,在SharePoint中称为 SPLINQ。同时相对于MOSS2007多提供一个SPRelatedField类,用来添加List之间的关联,也就是说SharePoint2010中允许设置参照完成性约束。

 

 

SharePoint2010中Content的继承层次关系如下图所示:

 

WebPart

1.       webpart page 是带有WebPart Zone 的ASP.NET页面,WebPart Zone相当于WebPart的占位符(PlaceHolder),添加WebPart的时候,可以选择将Webpart添加到哪个位置。

2.       每个WebPart页面都会有一个WebPart Manager对象,这个对象是用来Track每个WebPart添加的区域,并且保存和取得每个Webpart自定义和个性的数据。

在SharePoint中不直接使用ASP.NET的WebPartManager和WebPartZone,而是使用他自己的SPWebPartManager和SPWebPartZone两个对象完成以上功能,这两个对象是继承了ASP.NET中的两个对象而生成的。

在SharePoint2010中支持两种类型的WebPart,一个是System.Web.UI.WebControls.WebParts,另一种是Microsoft.SharePoint.WebPartPages.WebParts。

 

3.       创建WebPart有两种方式

(1)     可视化的Webpart编写方式

这种方式会创建一个UserControl,然后Load这个Control添加到WebPart的控件中,显示出来完成相应的功能。但是这种WebPart只能部署到Farm级别,因为生成的UserControl.ascx必须部署到SharePoint的虚拟目录”ControlTemplates”下,也就是说这个目录下的控件对当前Farm下的所有的SharePoint站点是可用的。如果需要灵活实现的话,可以将WebPart部署和UserControl分离开,可以创建站点级别的WebPart,但是在WebPart中引用“ControlTemplates”下的控件,这样就可以不受部署限制了。

(2)     纯代码WebPart

这种也是比较常用的一种方式,其实就是编写一个WebControl在Server端运行,这个控件中的显示,完成依靠后台的代码来实现输出和布局。


(7)        如果我们使用了SPSiteLockIssueOwnerSecondaryContact属性的时候,会隐式的调用RootWeb属性,那么这样我们必须对rootweb这个对象进行释放。例如:

SPSite site = new SPSite(serverUrl);

String str = Site.LockIssue;

Site.RootWeb.Dispose();

Site.Dispose();

webParentWeb属性为空的时候,我们使用的时候会调用OpenWeb方法来返回一个SPWeb对象,所以在程序最好释放ParentWeb的时候,我们需要判断一下ParentWeb对象是否为null,如果不为Null那就要对其进行释放。

(8)     当我们在try-catch-finally中使用Response.Redirect()方法进行页面重定向的时候,程序不会执行finally中的代码。因为在try中执行一个页面重定向的方法,会导致这个线程结束,并且产生一个异常,并且这个异常将会被运行时捕获,导致不会指定finally里面的代码。所以建议我们有页面跳转的时候要使用Using来释放相应的资源。例如:

不建议使用的方法

SPSite site = null

Try

{

            Site = new SPSite(“http://serverurl”);

            Response.Redirect(destUrl);

}

Catch

{}

Finally

{

If(site != null)

{

               Site.Dispose();

}

}

建议使用的方法

Using(SPSite site = new SPSite(“http://serverurl”))

{

            Response.Redirect(url);

}

如果坚持使用try-catch-finally那就必须在页面定向之前对非托管对象进行释放,例如:

SPSite site = null

Try

{

            Site = new SPSite(“http://serverurl”);

            Site.Dispose();

            Response.Redirect(destUrl);

}

Catch

{}

Finally

{

If(site != null)

{

               Site.Dispose();

}

}

(9)     我们使用UserProfile的时候可以返回一个PersonalSite,这个PersonalSite也是需要释放的

void PersonalSiteLeak()

{

   

    using (SPSite siteCollection = new SPSite("http://moss"))

    {

UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(siteCollection));

             UserProfile profile = profileManager.GetUserProfile("domain//username");

             SPSite personalSite = profile.PersonalSite;    //需要释放

     personalSite.Dispose();

    }

}

 

18.       调用COM需要手动释放资源

我们使用Trados SDK是以COM的形式进行调用的,所以在这里存在一个对COM对象进行资源释放的问题,因为COM对象不会自己进行资源释放,我们只能通过显示的调用GC进行资源回收。例如:

Application app = new Application();

Marshal.FinalReleaseComObject(app);

app = null;

GC.Collect();

GC.WaitForPendingFinalizers();

 

GC.Collect();

GC.WaitForPendingFinalizers();

这里需要进行两次调用

GC.Collect();

GC.WaitForPendingFinalizers();因为第一次只是对未释放的资源的统计,第二次才是真正的释放。第一次就是看有哪些COM对象的资源没有释放,而在第二则是根据第一次统计的结果进行对COM资源的回收。

19.      SharePoint Dispose Check Tool(内存泄漏代码检查工具)

主要用来检查我们编写的exe或是dll文件内部是否有SharePoint 对象使用的内存泄漏,可以在http://code.msdn.microsoft.com/SPDisposeCheck站点进行下载。

具体的使用方法:

安装这个检查工具,然后使用命令行运行这个exe,然后将要检查的exe或是dll拷贝到这个工具的安装路径下面,然后在这个SPDisposeCheck.exe sample.dll命令进行检查。 


20.       对于我们的系统,要有严格的异常处理机制和日志输出。在程序中输出日志,日志可以跟踪程序运行,当程序运行到一个地方,输出相应的日志,这样我们就可以根据日志的显示情况,知道程序运行的情况。方便定位程序出错的位置和修改。现在我们可以在服务器上直接调试,但是如果我们的系统做成产品,卖给客户的时候,我们是不可能在客户的环境上进行调试的,所以系统日志是必不可少的。主要是为了方便查找错误,然后解决问题。如果客户环境上出现问题,我们可以让客户将系统运行的日志给我们返回,这样我们可以根据日志就可以之后系统在客户端运行出现了什么错误,然后给予相应的解决方法即可。

21.       SPViewScope介绍

Default :仅显示指定文件夹下的文件和子文件夹

FilesOnly:仅显示指定文件夹下的文件

Recursive:显示所有文件夹下的文件

RecursiveAll:显示所有文件夹下的所有文件和子文件夹

以上这个属性使用在CAML中,用于控制在哪些范围内进行查找,我们可以根据实际的查找需求,对这个ViewAttribute属性进行设置,来完成我们的操作。

22.       SPGridView介绍

SPGridViewGridView的基础上,进行了一些扩展,也就是说他拥有GridView的所有功能,并且在其基础上有所改进。改进的主要是分组、分页、下拉菜单和filter功能。但是SPGridView不支持自动生成列,所以在使用的时候一定要将AutoGenerateColums属性设置成false

23.       JavaScriptreplace方法介绍

使用JaveScriptReplace方法,这个方法支持使用正则表达式,如果不使用正则表达式的话,默认只是会替换第一个匹配的字符。所以我们采用strM.replace(/&/g,"//")来将字符串中的所有目标字符。所以将这个方法和相应的正则表达式进行配合使用,功能将是非常强大的。

24.       在使用

SPFolder folder = web.GetFolder(url);

这样是通过url直接得到folder对象,没有经过list那个级别,对List的数据还可能没有进行初始化,所以使用folder.ParentListId可能是空,从而取不到List对象。也就是说不能取这个Folder对象的对应的Parent List的对象的属性。

25.  当我们对Web下的某些对象进行更新的时候,我们虽然调用了Web.Update()方法,但是SharePoint中的API不会将Web对象重新加载,也就是不会将一些新的MetaData从数据库中重新加载到Web对象中,这样就有可能造成对象不一致的现象。我们解决这个问题的方法是在我们使用Web的时候,要重新获取一下Web对象就可以了。

26.  使用CheckoutCheckin方法的时候,首先要判断进行操作的文件的状态,如果没有被Checkout,那就不能够被Checkin,如果是Checkout状态,就不能够再被Checkout了。同时对文件的CheckOut也就是相当于将文件添加了一个锁,标识一下这个文件的状态。如果这个文件被Checkout出去之后,其他人就不能够对其进行Checkout了,除非将其强制的Discard Checkout

27.  使用AllowUnSafeUpdate属性的一些需要注意的地方,这个属性是为了阻止不安全更新的属性,如果我们要对Web中的一些对象进行更新的时候,如果没有将这个属性设置成true将会出现一个验证异常。如果HttpContext.Current这个对象是Null的话,那么这个属性将永远是true。在使用这个属性的时候,一定要确定设置的是我们要进行更新的Web对象,如果不是,在更新的时候将会出现异常,因为以前我们对Web进行了一些操作,这样这个Web对象就发生了变化,不再是我们现在这个Web对象了,也就是导致了对象不一致,所以我们需要重新取得这个Web对象,然后再设置这个属性即可。

28.       一般在SharePoint部署的时候,我们使用WSP对一些文件进行部署,同时更新web.config,但是有些时候需要对web.config添加一些自定义的节点,并且可能修改原来的节点,所以使用WSP不能够完全满足我们的需求,应该使用WebConfigurationModification类对web.config文件进行修改。如下所示:

using (SPSite siteCollection = new SPSite("http://chris:11111/sites/testconfig"))

            {

                using (SPWeb site = siteCollection.OpenWeb())

                {

                    site.AllowUnsafeUpdates = true;

                    SPWebApplication app = siteCollection.WebApplication;

                    SPWebConfigModification modification1 = new SPWebConfigModification();

                    modification1.Path = "configuration";

                    modification1.Name = "connectionStrings";

                    modification1.Value = " <connectionStrings></connectionStrings> ";

                    modification1.Owner = Assembly.GetExecutingAssembly().FullName;

                    modification1.Sequence = 100;

                    modification1.Type

=SPWebConfigModification.SPWebConfigModificationType.EnsureSection;

                    app.WebConfigModifications.Add(modification1);

           

                 SPWebService service = SPFarm.Local.Services.GetValue < SPWebService >

();

                    service.ApplyWebConfigModifications();

            }

      }

 


0 0