I’ve got an event handler on a SharePoint list that’s fairly long running, and this then raised a question in the office – do these settings control event firing for the currently running event handler, or for the entire list?
Very often you see lines of code like this…
this.EventFiringEnabled = false; item.Update(); this.EventFiringEnabled = true;
… but was this really necessary? Are people worried about events not being handled ‘cos firing is disabled, or is this just a convenient way of tracking whether events are enabled or not?
My feeling was it wasn’t. The setting (DisableEventFiring in 2007 and EventFiringEnabled in 2010) must be for the current event handler; if it was the entire list there’d be all sorts of timing issues and weirdness, and a thousand developers would already have screamed in agony. A quick check on twitter suggested the same – that it was the thread (thanks @ChrisO_Brien). I became curious, though, and wanted to see how it worked.
Time to use SharePoint Dev Tool #1 (Reflector) on the SPEventReceiverBase class…
So EventFiringEnabled calls a static method on the SPEventManager object – sounds reasonable, let’s look at that:
Okay, so we’re setting a private static LocalDataStoreSlot to mark whether event firing is enabled or not. This LocalDataStoreSlot is in the SPEventManager class, and being static, it’ll be shared across the entire thread, for that current domain.
This is interesting, as it leads to an interesting scenario – if you were creating additional threads from your Event Receiver’s thread, then event firing will not be disabled on those. I can’t think why you’d want to do that, but there you go.
Alternatively, if you were using an event handler to update another list, you might be able to disable the events on those. (I’ve not tried this.)
Finally, if you wanted to turn off or on event firing from your own code, without an event handler – like if you were creating a number of items from a console application, etc. :
private static void EventFiringEnabled(bool enabled) { Assembly assembly = Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); Type type = assembly.GetType("Microsoft.SharePoint.SPEventManager"); PropertyInfo pi = type.GetProperty("EventFiringDisabled", System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.NonPublic); pi.SetValue(null, !enabled, null); }
Obviously, you’d build a proper wrapper for this (and not load the assembly each time) but it proves the point. Also, note that the SPEventManager‘s property is EventFiringDisabled.
I guess what we really need is an Update() method on an SPListItem that won’t fire events; that would be simpler.
Your comment <> Is exactly the scenerio I was seeing that caused me to Bing and find your posting..
I was disabling the event firing on an itemupdating handler, but this handler writes data to another list, that list has workflow associated with it (fires on item create) and it was NOT firing… I had to set EventFiringEnabled = true just before the call to write to the second list, then set it back to its previous value…
Thought this update might help someone else.
So If I read correctly the this.EventFiringEnabled = true; disables the event receiver on the given list for all the record within the list.
or is it
that is disables the event receiver for the given record on which the event received was initially launched.
Thank you for the help
Neither. It disables all event firing for any events caused in the current thread. This include all records within the list – or within any other lists. If your event handler on list A caused an update in list B, and EventFiringEnabled was false, then no events would be fired in list B.
I’ve written a console app that uses the SP object model to update a property/column value of an item in a document library. So the code is as simple as:
item[“some column”] = “some value”;
item.Update();
The console app is executed as an SP administrator on the SP front-end server, so there is no issue with security, rights, etc. as far as I can tell. But then the following output gets spit out on the console window, and I am wondering if there are any adverse side effects because of it, and if it has anything to do with the topic of your article. The item value does get updated, by the way.
1 2/19/2012 10:23:47 AM ItemUpdating http://server/sites/web/Shared Documents/Document01.pdf > http://server/sites/web/Shared Documents/Document01.pdf
1 2/19/2012 10:23:47 AM ItemUpdating SetID: Key=shared documents/Document01.pdf value=
0002871
634652438271779415
false
false
10 2/19/2012 10:23:47 AM ItemUpdated SetValue: 0002326
Well, unless you don’t want those ItemUpdating and ItemUpdated events firing, no, it probably is not related.
I would check who your code is running as. I’m not clear what you mean by an ‘SP Administrator’. Do you mean a ‘Site Collection Administrator for the site I’m working in’? ‘Cos a Farm Admin does not have guaranteed access to any content. Alternatively, use elevated privileges and have your code run as the App Pool account.
Note that from a console app, Item event handlers will run as the account running the console app. Within IIS, though, the process would run as the app pool account.
Thanks for the information.
This simple solution looks nicer than using reflection and is exception safe: http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/