Enterprise MOSS 2007: Event Receivers and threads don’t mix

MOSS provides an Event Receiver model you can use to perform actions when something happens (i.e. a list item is updated). This is somewhat described here:

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.speventreceiverbase.aspx

It can be easy to end up in a loop here; for example, if you handle the ItemUpdated event, and you update the item again inside your event receiver, then your event receiver is going to fire again, causing you to update the item again, which will cause the event receiver to fire, causing you to … well, you get the picture.

SharePoint does have built-in protection for this problem, though – it will only allow a “depth” of 10 recursive events to fire.

Additionally, to solve this problem, the SharePoint object model provides two methods that can prevent this:

image

This all works great, but the solution I was working with on this problem required a somewhat “mass processing” of a bunch of list items. To do this, the event receiver spawns a few new threads for processing list items. We started getting some very weird errors – my favorite?

WebPartPageUserException: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

In any case, what we actually found was that DisableEventFiring and EnableEventFiring, quite frankly don’t do jack when it comes to other threads. Why?

They set a property in the SPEventManager class:

image

Which, in turn, flags some data on the current thread!

image

On one hand, this makes sense, from the HTTP model perspective (you don’t want to disable events globally, because other updates coming from a browser wouldn’t fire the initial events while you were still processing yours), but at the same time, it’s far from obvious that asynchronous multithreading is not supported in the event model.

Lessons learned:

  • The SharePoint event model is NOT friendly to multi-threading. If possible, offload asynchronous operations to a timer job or another method that will take place in a single thread / SharePoint request context.
  • For multi-threaded operations, make sure the threads you spawn disable events before updating any items, to avoid an infinite loop.
  • Anesmesse

    11111

  • andrei

    catastrophic failure - i lold 🙂