我有几个关于在 Sharepoint 中开发多线程 webpart 的问题。首先,让我解释一下这个想法。我有一个包含 5-7 个不同 Web 部件的页面。这些 webpart 都是以相同的方式构建的,这意味着:
a) 从一些 SPLists 中检索一些数据
b) 将该数据转换为 xml
c) 执行xslt转换生成html
d) 在 RenderContents 方法中输出 html 内容
这个过程对于单个 webpart 大约需要 500ms。
现在我的想法是使用线程进行一些性能调整。前面描述的所有过程都可以在最好的情况下在执行管道的早期方法(例如 OnLoad)中或在最坏的情况下在 OnPreRender 方法中由线程执行。在 RenderContents 方法中,我可以在最坏的情况下等待线程完成(当然在这里我会实现一些超时逻辑)。
Q1) 使用这种技术应该可以提高页面的性能,对吗?
我的假设:我在页面上有 5 个 webpart,一个 webpart 需要 500 毫秒
之前:执行时间为 5*500ms = 2500ms。
之后: Max(wp1, wp2, wp3, wp4, wp5) 在我的例子中是 500ms。
现在,我的第一个问题:Q2)我是对的吗?如果不是,为什么?
现在让我们更详细地谈谈实现。我应该使用哪种技术?
- 创建一个新线程,然后调用 Thread.join()
- 使用线程池
- 或者在 OnPreRender 中调用 Page.RegisterAsyncTask
在这一点上,我还有一些其他问题:
Q3) 因为,我使用的是 SPSite,并且我读到这个对象是基于 COM 的,我可以使用 ThreadPool 或 Page.RegisterAsyncTask 吗?在一些博客中,我读到 ThreadPool 不支持 COM 对象,因为是公寓模式(MTA 与 STA)。此外,我认为 Page.RegisterAsyncTask 也在使用 ThreadPool。
Q4) 你会建议我哪种实施/架构?
Q5) 如果我要在 OnPreRender 方法中使用 Page.RegisterAsyncTask,我是否确定在方法中 RenderContents 仅在所有任务完成时才被调用?
我尝试使用 Threads 实现,但它似乎不起作用。一旦我尝试访问 SpSite,我就会收到以下异常:
在 Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx) 在 Microsoft.SharePoint.Library.SPRequest.GetTokenOfCurrentUser(Boolean bWindowsMode, String bstrLogin, String bstrUserKey, String bstrRoles, UInt32 ulRoleCount) 在 Microsoft.SharePoint.SPSite.InitUserToken(SPRequest request)在 Microsoft.SharePoint.SPSite.SPSiteConstructor(SPFarm 场,Guid applicationId,Guid contentDatabaseId,Guid siteId,Guid siteSubscriptionId,SPUrlZone 区域,Uri requestUri,字符串 serverRelativeUrl,布尔 hostHeaderIsSiteName,SPUserToken userToken)在 Microsoft.SharePoint.SPSite..ctor(SPFarm场,Uri requestUri,布尔 contextSite,SPUserToken userToken) 在 Microsoft.SharePoint.SPSite..ctor(String requestUrl)
我尝试使用 Page.RegisterAsyncTask 实现,但出现以下异常:
试图在单线程模式下调用多个线程。(来自 HRESULT 的异常:0x80010102 (RPC_E_ATTEMPTED_MULTITHREAD))在 Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx) 在 Microsoft.SharePoint.Library.SPRequest.SetIPAddr(String bstrIPAddr) 在 Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(SPSite 站点,字符串名称, Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous) 在 Microsoft.SharePoint.SPWeb.InitializeSPRequest() 在 Microsoft.SharePoint.SPWeb.GetList(String strUrl)
我怎样才能实现这样的架构?
亲切的问候