There is a lot of confusion around the web on how to disable (and/or) enable an Event Receiver; specifically people are trying to circumvent issues most of the times related to concurrency exceptions when uploading a file, where an Edit Form shows up and filling it’s value sometimes leads to the list item trying to update itself but is an inconsistent state – surely enough SharePoint blocks you from doing that by throwing.

I’ll make this a snap – the *ONLY* accurate, reliable and supported way of disabling/enabling/toggling the status of an Event Receiver is:

SharePoint 2007
    public class EventReceiver : SPItemEventReceiver
    {
        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            this.DisableEventFiring();
            properties.ListItem.Update();
            this.EnableEventFiring();
        }
SharePoint 2010
    public class EventReceiver : SPItemEventReceiver
    {
        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            this.EventFiringEnabled = false;
            properties.ListItem.Update();
            this.EventFiringEnabled = true;
        }

Now let’s take about this alluring SystemUpdate() method call. Wow, SystemUpdate(), hmmm… sounds powerful “System”Update. Well, it’s not. It should only be used for what it’s supposed to (verbatim from MSDN):

Updates the database with changes made to the list item, without effecting changes in the Modified or Modified By fields.

When you implement the SystemUpdate method, events are triggered and the modifications are reported in the Change and Audit logs, but alerts are not sent and properties are not demoted into documents.

If your scenario does not involve any of the above mentioned situations like not modifying the (user, time), alerts, or document promotions, then this is not what you need. If you’re using SystemUpdate() for not updating the list item version, etc. use UpdateOverwriteVersion() instead.

With all that said, there are cases when you need to use SystemUpdate(). One good example of it’s use in our codebase is in the Discussion Board list type, where it is able to update the discussion post, it’s reply count, etc. without affecting the original post’s user, time, etc.

UPDATE: Forgot to mention DisableEventFiring and EnableEventFiring are Obsolete API in SharePoint 2010.