5

When I register an ItemEventReceiver to a List in a SharePoint farm, when & where will it get instantiated, and when & where will its event-handling-methods be called?

The options I could imagine:

  1. Instantiated ONCE on ONE server in the Farm
  2. Instantiated ONCE on EVERY server in the Farm
  3. Instantiated MULTIPLE TIMES on EVERY server in the Farm
  4. Instantiated ONCE for EVERY active item, then garbage collected after item is inactive for some time (so if an eventreceiver instance for an item gets created on one server, there will be no more instances be created on any server, until this event receiver gets garbage collected)

If options 2 or 3 are the case, can events for the same item be fired on different instances? Or will events for the same item always fire in the same instance? For example: there is one event receiver instance on server 1, and 2 instances on server 2. Now item X gets updated 2 times in a row. Is it guaranteed that always the same of those 3 instances handles the event?

UPDATE

As I don't get the answers I need, I'll provide some background why I need this information:

I'm developing a software that listens on every file upload or change. When the event fires, an external software gets notified via a HTTP request. The software then modifies the file and uploads it back to sharepoint. To do so, it checks it out, adds some fields to the file, updates the content and then checks it back in. Those operations trigger the SPItemUpdated event again multiple times.

But of course, for those events, I don't want to notify the external software again. The EventReceiver needs to keep track of when the external software starts modifying the file and when it's done and ignore events in between for the specific files.

To find a good strategy for this, it is very important to know the lifetime of an eventreceiver object. For example, if the eventreceiver only runs once, I can keep track of the state of the files in memory. Instead, if the eventreceiver gets called multiple times, every eventreceiver will have it's own states and it would not work. Except there is some guarantee that a file is never processed by different instances, then it would not matter.

I hope you understand now, that is indeed important to know the lifetime of an instance.

2
+100

I'll add my 2 cents.

If event receivers were developed with care and best practices, it should run only once. And always runs on a web front end server (w3wp) in normal circumstances. When you Add/Update list items via Console APP on the server or via PowerShell - the receiver will run as part of the console or PowerShell process respectively. If TimerJob updates list item - then the event receiver will be executed inside OWSTimer.exe.

Reasons why event receivers might run more than once:

  • The same event receiver was registered multiple times
  • It was registered both for Added and Adding/ Updated and Updating events
  • If you created an event receiver for the document libraries. Every time you upload a new document - Item Adding/Added will be followed by Updating/Updated. If you use the same instance of the event receiver for all of these events - it will be run multiple times.
  • Event receivers call each other in a sequence.
  • There is a Workflow process that updates your list item

enter image description here

  • This is an interesting answer, thank you!When you Add/Update list items via Console APP on the server of via PowerShell - the receiver will be run as part of the PowerShell process. Does that mean, that when the external software updates an item, the item's event receiver actually runs inside the external software's process? – Van Coding Oct 5 '17 at 12:41
  • @Van Coding, no, it means that it runs in w3wp process, on the front-end. Everything external behaves this way. – Denis Molodtsov Oct 5 '17 at 13:41
  • What do you mean by a console app then? My "external" app IS a console App, running a HTTP server that listens for requests from the eventreceivers, and it uses the Microsoft.SharePoint.dll to get & update items. – Van Coding Oct 5 '17 at 14:04
  • I oversimplified my explanation. Now I regret it. Event receivers will run inside the console app process only if it runs on the SharePoint server itself and the console uses Server Side Object Model (SSOM) to work with SharePoint. Same goes for PowerShell. If you run Standard server SharePoint Commandlets from Microsoft.SharePoint.Powershell - then it's a powershell process. If you are using something like PnP - it's going to be W3WP process – Denis Molodtsov Oct 5 '17 at 16:48
1

If you update a Listitem in a ItemUpdated EventReceiver and call an item.Update() inside this receiver, you fire new ItemUpdated Events. To prevent this behavior, you can set EnableEventFiring to false. As far as i know, this will disable eventfiring for the entire SiteCollection, but there is no other "out of the box" way to do this :(

Disable Events from firing new Events

  • This is the correct answer but to do what Van wants he'll need to create a custom web service to handle this as his app appears to be external. – Bunzab Oct 4 '17 at 9:43
  • Yes, that won't work for me. I cannot afford to lose any event. But what if I kept an in-memory list of item urls for which to ignore events, would I have some guarantee that the event won't fire in another instance of the event receiver, that has a different list? – Van Coding Oct 4 '17 at 10:05
  • I think you can only achieve this with a custom solution. in-memory list of items could bring some issues as well. What if the process is terminated or the server reboots or ...?! Maybe you could work with a timerservice, if you dont need the changes immediately? You could check if the item you want to update is already listed in the (lets call it) "upcoming timer jobs". But it take some custom code. Otherwise Bunzab's idea with a web service could help you out, too. – ReTech Oct 6 '17 at 8:59
0

Updated to match revised question

The lifetime of an event receiver object is for the action occurring. For example, if you were to override the ItemAdding event you intercept the item as it is before it is added. Obviously an item can only be added once, so ItemAdding (before it is actually added) and ItemAdded (immediately after its added) will only execute once.

OnUpdated events will occur anytime the item is changed. This would include files being renamed, metadata being added to the item by updating fields, or updating the document. Items can be updated multiple times, so this event will fire every time. It will not fire at the same time as ItemAdded.

To suit your scenario, you would want to use the ItemAdding event to capture the item and document prior to it being added to the library. You can then contact your 3rd party software, receive the metadata, add the metadata to the item, then allow the procedure to continue.

Since the ItemAdding or ItemAdded event only fires when the document is originally added to the library, you don't have to worry about multiple outside calls.

ItemAdding Event Receiver on MSDN

  • 1
    Thanks for that answer :) It sadly does not fit my question – Van Coding Sep 28 '17 at 15:06
  • It's a very broad question, and the way you've phrased it confuses the actions of the event receiver with its deployment. If the event receiver for the list has been deployed correctly, it doesn't matter which web front end handles the action, it will only fire once per action. – Jack Oct 2 '17 at 10:30
  • I've updated my question. – Van Coding Oct 3 '17 at 7:45
0

Have a checkbox on your list "External Software Modified."

Have the external software always check that box when making a change.

Have the ItemUpdated event receiver check this field. If it's checked, do not execute the rest of the code. At the end of ItemUpdated, always uncheck "External Software Modified" and save with event firing disabled.

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.