SharePoint Document Library Event Handlers & "Locked for Editing" Status
In my previous post I described a problem I was having while implementing a generic SharePoint Document Library Event Handler. When you save a document from Office 2003 (for example Word 2003) into a SharePoint Document Library, the document item in the library is “locked for editing” as long as the Office 2003 application stays open. This can be a problem, for example when you want the Event Handler to update a field of the document item when it’s submitted to the Document Library. There are no problems when using the web interface, but when a user does this by using Office 2003 you’ll end up with the following exception:
Microsoft.SharePoint.SPException: Document Locked
The document you are attempting to edit is locked and cannot be updated. It may be in use by another user or undergoing content indexing.
Too bad there isn’t even an event that the Event Handler can intercept when the document is un-locked (when the user closes the Office 2003 application). So I came up with following solution: you can use the CheckOutStatus property of the SPFile class to check if the document item is locked. The CheckOutStatus property can have three values:
- LongTerm
Specifies that the check-out is long-term. - None
Specifies that the file is not checked out. - ShortTerm
Specifies that the file has been opened by a user and is locked for editing. A short-term check-out, or file-locking, only has effect as long as the application renews the lock.
As long as the CheckOutStatus property is not equal to None, I suspend the thread that’s handling the event. You can do this pretty easy in a loop:
public void OnEvent(SPListEvent listEvent)
{
SPFile file = web.GetFile(listEvent.UrlAfter);
while(file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
{
System.Threading.Thread.Sleep(1000);
file = web.GetFile(le.UrlAfter);
}
}
The second line in the while code block is needed to refresh the values of the SPFile object. I’m not completely happy with the solution, my first concern is that when the IIS Worker Process gets killed, all the event handlers that haven’t finished are lost. So the worst case scenario is that for example the IISRESET is used when an event handler is in the while loop. My second concern is scalability: when a lot of users submit a lot of documents at the same, possibly a lot of threads could be sleeping, so a lot of threads could be active which could lead to some performance issues. Well for now I can live with these concerns, just keep in mind when you use this approach what the consequences are. In my opinion, the cleanest solution would be that SharePoint only raised events when the document is un-locked...