SharePoint event receivers are of two types: synchronous and asynchronous. Synchronous event receivers will fire before the event is completed (for example, event receiver for the ItemAdding event). Whereas, asynchronous event receivers will fire after the event has completed (for example, event receiver for the ItemUpdated event).
You can think of SharePoint events as “…ing” vs “…ed” events.
- Synchronous (Before events)
- ItemAdding
- ItemUpdating
- ItemDeleting
- Asynchronous (After events)
- ItemAdded
- ItemUpdated
- ItemDeleted
The above is just a small sample. There are many other events available to you: ItemAttachmentAdding, ItemAttachmentAdded, etc.
Here’s some more detail about how synchronous events work compared to asynchronous ones:
Synchronous event:
- Fires before the event.
- Blocks the flow of code execution until your event handler completes.
- Provides you with the ability to cancel the event so that the asynchronous/after (“…ed”) event will not be fired.
Asynchronous event:
- Fires after the event
- Does not block the flow of code execution.
So, why would we ever want to make an asynchronous event synchronous? Why not just use its synchronous counterpart?
The problem…
Let’s say you want to update the Title field value of a document with the actual file name (the Name field) every time a file is added to a certain document library. To do this, you have created an ItemAdded event receiver and attached it to the library. The Elements.xml file of your event receiver should look something like this:
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Receivers ListUrl="TheUrlOfYourDocumentLibrary"> <Receiver> <Name>SyncEventReceiverItemAdded</Name> <Type>ItemAdded</Type> <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly> <Class>SyncLists.SyncEventReceiver.SyncEventReceiver</Class> <SequenceNumber>10000</SequenceNumber> </Receiver> </Receivers> </Elements>
Now if you upload multiple documents to the library in one shot, everything works as expected. The edit screen does not come up. After the documents are uploaded, your event receiver fires and uses your code to update the Title fields of each document as required. No problems there.
The problem appears when you attempt to upload a single document. This time, after the document has been added to the library, the edit properties screen will come up. Let’s assume that the initial version of the document at this point is version 1.0. When we press OK on the edit properties screen, our ItemAdded event will fire. Since we’re updating the Title field of our item within the ItemAdded event, the document version will change to say version 1.1 after the update. Because the version number at the beginning of the upload operation is now different from the version number inside our ItemAdded event handler, we will get a save conflict error.
Note: This problem only occurs if the edit properties page comes up when single documents are uploaded. If you don’t have any required fields on your document library, the edit properties page may not come up at all (in which case, this problem may not exist).
Anyways, if you encounter the edit properties box on single document uploads and still want to run custom code in the ItemAdded event receiver, here’s an approach to solving the problem.
Making asynchronous SharePoint event receivers synchronous
To solve this problem, we need to make the ItemAdded event receiver behave synchronously. So that, by the time the edit properties page is loaded, our ItemAdded event receiver would have already completed its operation and the edit properties page will be loaded with the updated list item.
To do this, we just need to modify our Elements.xml file to include a Synchronization element.
Like this:
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Receivers ListUrl="TheUrlOfYourDocumentLibrary"> <Receiver> <Name>SyncEventReceiverItemAdded</Name> <Type>ItemAdded</Type> <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly> <Class>SyncLists.SyncEventReceiver.SyncEventReceiver</Class> <SequenceNumber>10000</SequenceNumber> <Synchronization>Synchronous</Synchronization> </Receiver> </Receivers> </Elements>
Leave a Reply