韓鳳寧
同濟大學軟件學院,上海 330027
EventHandler在SharePoint中起到事件處理的作用。當用戶使用SharePoint進行一些操作時,比如上傳一個文件,EventHandler相應的事件處理函數便會截獲此事件,執行開發人員在此函數中重寫的功能代碼,從而實現一系列動作事件。在SharePoint中,EventHandler依據SharePoint的層次結構和功能分為 Web Level、List Level、ListItem Level、Email,分別繼承了SPWebEventReceiver、SPListEventReceiver、SPItemEventReceiver、SPEmailEventReceiver類。開發人員根據實際需求在相應的子類中實現具體的功能。
該類的命名空間為Microsoft.SharePoint.SPItemEventReceiver,用來處理發生在ListItems上的觸發事件。開發人員創建子類,并繼承SPItemEventReceiver類,來實現實際問題中的觸發事件。圖1為SPItemEventReceiver類的結構。

圖1 SPItemEventReceiver類結構
當用戶向文檔庫上傳文檔時,要用到SPItemEventReceiver類的ItemAdded()方法去處理文檔上傳時的一系列動作。在實際需求中,會在SharePoint項目中引入外部動態鏈接庫,即調用DLL文件。在此介紹的DLL文件實現的功能是將上傳的文檔進行文字提取,這個文字提取的執行過程將會占用至少1分鐘的時間。如圖2為事件觸發后的一系列過程。
在ItemAdded方法中調用外部動態鏈接庫,在實際項目開發中是經常會遇到的情況,然而這也引起了一些問題。如果外部動態鏈接庫不支持多線程,那將會在執行過程中出現一些異常,從而使上述系列過程不能正常完成。當用戶在上一個過程還未完成時就上傳了第二個文檔,那么這時,第二個文檔的線程會終止掉第一個文檔的線程,造成第一個文檔無法處理完成。

圖2 觸發后處理的事件
ItemAdded本身是支持多線程的,但是由于外部動態鏈接庫的引入,而這個動態鏈接庫并不支持多線程,這就造成多次觸發時,不能正常完成每個文檔上傳后的整個處理過程。這時的解決方法,就是在ItemAdded方法中手動創建線程。每當ItemAdded被觸發,就創建一個線程,來單獨處理本次觸發后的系列過程。由于調用動態鏈接庫的部分是不支持多線程的,所以這部分的執行代碼將被放到共享池中作為共享資源被加鎖。具體執行代碼如下:



在Sharepoint EventHandler中支持多線程,可以把占用長時間的觸發過程放到后臺處理,使得EventHandler得以空閑出來去處理下一個觸發過程,而且下一個觸發過程并不會影響上一個過程的執行,這樣就保證了每一個觸發過程單獨完整的執行。
[1]http://blog.csdn.net/forever_kingdom/article/details/4516651.
[2]Multithreading Part 2: Understanding the System.Threading.Thread Class.http://www.c-sharpcorner.com/UploadFile/mmehta/Multithreading211162005044506AM/Multithreading2.aspx.
[3]Scot Hillier.Microsoft SharePoint Building Office 2007 Solutions in C#2005Apress, 2007.
[4]John Holliday,John Alexander.Professional SharePoint 2007 Development Wiley Publishing Inc.