Monday, March 26, 2007

SPItemEventReceiver - ItemAdded and ItemUpdated runs simultaneous

I have created a lot of event handlers over the last months, but sometimes I cannot get them working properly. From time to time it seems that item-events are running in sequence, i.e. ItemAdded then ItemUpdated. However, in other situations ItemAdded starts - but before ItemAdded finish ItemUpdated starts. I would like to ensure that one event is completed before the next is kicked off. Any hints.

It appears that is it critical to use SystemUpdate(...) rather than Update() as outlined here. But a note claims this was only an issue for beta versions?

I have tried using SystemUpdate rather than Update as sketched below, read this blog.
this.DisableEventFiring();
anItem.SystemUpdate(false);
this.EnableEventFiring();

The sequence of events is also quite strange as outlined in many blogs, try reading this.

Solution: It seems that if you ensure using SystemUpdate and Disable/Enable EventFiring as sketched above consistently in your eventhandler you don't have any issues. But I'm not yet convinced.

10 comments:

David said...

Hi Morten,

I've just starting working with Sharepoint 2007 event handlers too and often experience very random errors. After looking for resources on the net, it always boils down to using the following (as you have discovered too):

this.DisableEventFiring();
anItem.SystemUpdate(false);
this.EnableEventFiring();

This does work to an extent. But somehow I still find my my ItemUpdated event firing more than once. I then debugged my events and found out that the events are firing multiple threads at the same time. This can be seen with the stepping behaviour of the code execution and by clicking on "Debug --> Windows --> Threads". Clearly multiple threads are executing at the same time. This should also explain why it seems like some events are triggered before others are. The problem grows when I see 2 threads are running for the ItemUpdated event and 1 thread running for the ItemCheckedIn event.

I only discovered this tonight, and am still trying to figure out why this happens. More specifically, I need to know why the ItemUpdated starts another thread. Any ideas would be helpful.

Morten Marquard said...

You might try to
li.UpdateOverwriteVersion()

I tried that - and it helped me a bit. Not sure what the difference is between the two functions. As anything with SharePoint the documentation is an area for improvement.

swati said...

Hi all
In my case ItemAdded event is geting fired but the code under that simply dosent work , i have checked the code separately using web application its working fine ther that means ther is no problem in code . i m not geting why its not runing under event handler .. can any body help me out .thanx

Anonymous said...

Perhaps you can use something like this: (works for me)


class myEventReceiver: SPItemEventReceiver
{
static readonly object _lock = new object();

public override void ItemAdded(SPItemEventProperties properties)
{

lock (_lock)
{
// Rest of the code that needs to be locked
this.DisableEventFiring();
anItem.SystemUpdate(false);
this.EnableEventFiring();
}
}
}

Juha said...

I found your posting a couple of months ago when trying to tackle a problem of same nature. My case was to create a new discussion when a new item was added to Pages-library and save the information of the location of the discussion to the item's meta data. I ran into problems with the same scenarios you described: ItemAdded wasn't complete when ItemUpdated was already firing. This is because the methods are called asynchronously. So when the ItemUpdated went through and the ItemAdded was continued, the task I was trying to achieve in code level caused an exception because the item had been updated "page has been updated". I tried all the solutions in this thread with no success.

Then I realized the ItemUpdated fires anyway always when an item is added. So I just removed everything from ItemAdded and did my deeds in ItemUpdated and got rid of all the problems.

Morten Marquard said...

Thanks. Quite scary that ItemAdded should not be used. Will modify to using ItemUpdated.

Juha said...

"Quite scary that ItemAdded should not be used."

I wouldn't go that far but this is one thing to consider when designing ItemEventReceivers to Pages-list where you want to update the item itself (which fires the event) as in many cases you do.

Biju said...

Hi David,

I'm overriding the ItemUpdating event, here I have 2 fields "Start Date" and "Due Date". Now whena user edits the Start date of an item and clicks "OK",I need to capture the previous and latest start date and compare them.

I'm able to getthe previous date by the following code

SPWeb contextWeb = properties.OpenWeb();
SPList spList = contextWeb.Lists[properties.ListId];
SPListItem contextItem = spList.GetItemById(properties.ListItemId);


current_id = Convert.ToInt32(contextItem["ID"]);

if (contextItem["Start Date"] != null)
current_StartDate = (DateTime)contextItem["Start Date"];

But am not able to get the latest(committed) Start date.

I tried using the AfterProperty, but no luck :(

if (properties.AfterProperties["Start Date"] != null)
updated_StartDate = Convert.ToDateTime(properties.AfterProperties["Start Date"]);


Can you help me in finding the solution for the same

With regards
Biju

Anonymous said...

Good brief and this post helped me alot in my college assignement. Say thank you you on your information.

Anonymous said...

Hi All, I want the user to be redirect to success page as soon as item is been added to the list and asynchrounously send an email to the user. I created an itemadded event which get fired when i add the item to the list with console app but the same event doesn't get fired from the sharepoint site. Any ideas ??