In Sharepoint, the attached item events are fired whenever you perform an item.Update()
Ryan posted a solution to this issue, using a custom event handler that disables the events upon request.
What I dislike about the solution, is the risk of leaving the events disabled. Assume an exception occurs, the code will never reach the line where the event firing is enabled (restored) again.
I suggest a using-pattern, much like the TransactionScope class used for db transactions in the entity framework.
class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
{
public DisabledItemEventsScope()
{
base.DisableEventFiring();
}
#region IDisposable Members
public void Dispose()
{
base.EnableEventFiring();
}
#endregion
}
Now we can use this class together with the using syntax to create a scope within all item event firing is disabled.
using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
{
item.SystemUpdate(); // will NOT fire events
}
item.SystemUpdate(); // will fire events again
This way, the event firing is enabled again as soon as the code leaves the defined scope, be it through normal operation or by exceptions.
Update 1
For SharePoint 2010, use this snippet instead:
/// <summary>
/// Disabled item events scope
/// </summary>
/// <see cref="http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/"/>
class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
{
bool oldValue;
public DisabledItemEventsScope()
{
this.oldValue = base.EventFiringEnabled;
base.EventFiringEnabled = false;
}
#region IDisposable Members
public void Dispose()
{
base.EventFiringEnabled = oldValue;
}
#endregion
}
Thanks!!! it works
Great, this solution is simple and very bright, but instead of use the using-pattern is not better use a try-catch-finally? Because if code generate an exception inside the using statement, the event handler is not more enabled!
The “using” statement is being translated to try/catch/finally anyway. Therefore if an exception occurs within a using block, it will call the Dispose(..) method of the using-object
i am a beginner at SP workflow and facing the same issue. I have a few fields that are updated as part of workflow, i dont want to trigger a new instance when those are updated. I understand the logic but can you show me where to update the event handler?
Hey, Kanchan
I am facing the same problem as you
Where did u put the code?
base.DisableEventFiring() & base.EnableEventFiring() have both been made obsolete in SharePoint 2010.
Use the boolean property base.EventFiringEnabled instead.
Such a clean solution! Thanks <3
much gr8 post !!!
Fantastic! Thank you!
This solution was a HUGE help in our battle to resolve “The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request.”
This particular error only occurred in some environments, not all. We opened a Microsoft support case, too, but ended up coming up with a workaround ourselves based on this method of disabling event handlers.
Our traditional method of disabling event handlers from firing was to set “this.EventFiringEnabled = false” in, for example, the ItemUpdating event handler.
However, we discovered in some environments, for some unknown reason, the flag would be reset to true and the event handlers would fire recursively, thereby causing the [not very helpful] “too busy to handle the request” error.
can we use this code in timer job?