韩凤宁
同济大学软件学院,上海 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.