6

Is it possible to use SPWeb.ProcessBatchData() and not trigger all the event handlers attached to a list?

I would like to process a large list in quick time, but I don't want all the event handlers attached to the list getting fired

11

We faced the same problem at work recently. And there are two good options here we've found:

1. Global variable

Use SPWeb.Properties or some other SharePoint property bag, and use kind of "global variable" trick: you set this variable to "ON" before the batch is executed, and set it to "OFF" later when the batch is finished. And in your event receivers, obviously, you will need to check the value of this property, and break the execution if it is set to "ON".

If you have your event receivers code and the batch code in same assembly, you may consider to use some static field (for example, in the event receiver class) for this purpose, rather than persistent property storage.

2. DisabledEventFiringScope

The second approach is much more tricky and looks like a hack, but it actually can save you, if you don't have access to the receivers code, or if you have your receivers classes clattered over different solutions and you don't want to manage them, etc.

The point here is that when you use EventFiringEnabled in some event receiver, actually it disables execution of event receivers in the whole thread (because internally, this functionality uses ThreadStatic variable).

Having this knowledge in mind, you can implement your own IDisposable class, inherit it from SPEventReceiverBase class, disable events in its constructor, and enable them back in the Dispose method.

Thus, you will be able to use the DisabledEventFiringScope class following way:

using (var disabler = new DisabledEventFiringScope())
{
    web.ProcessBatchData(batchXml);
}

And here is the code for the DisabledEventFiringScope class:

class DisabledEventFiringScope : SPEventReceiverBase, IDisposable
{
    public DisabledEventFiringScope()
    {
        EventFiringEnabled = false;
    }

    public void Dispose()
    {
        EventFiringEnabled = true;
    }
}

(this approach is based on the following article: http://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/)

  • 1
    Didn't know we could use disableEventFiring scope for batch processing too. Great answer, thanks! – ashwnacharya Jan 7 '12 at 23:29
0

Theoretically, it might happen situation than you prevented event firing and user added item throught web interface exactly at this time. So, user added item wouldn't be processed by the receivers, but it have to. I think, it's better to check event receiver variable at the SPListItem level. For example, you can add hidden field to list and fill it in batch adding xml. So, you can check does this item added throught batch or throught web ui.

  • 1
    I think its not possible, because for user request separate thread will be created, and in this thread EventFiringEnabled will be true. – Sergei Sergeev Jan 8 '12 at 9:04
  • Yes, it might be so. It's very interesting to know does EventFiringEnabled thread depended or not. – IAfanasov Jan 8 '12 at 9:45
  • With disassembler i found what SPEventReceiverBase.EventFiringEnabled is thread specific. So, my theory isn't right. Thank, Kai :) – IAfanasov Jan 9 '12 at 6:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.