Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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

share|improve this question

2 Answers 2

up vote 10 down vote accepted

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/)

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

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.

share|improve this answer
1  
I think its not possible, because for user request separate thread will be created, and in this thread EventFiringEnabled will be true. –  Kai 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

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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