I’ve been having a problem with an app I wrote.  It works great, 99% of the time, but sometimes the ItemAdded event appears not to fire.

Now this is using a list with over 20,000 entries in it and its growing all the time.  An associated list that references this list as a lookup has over 144,000 entries in it.

The event firing problem is becoming more frequent now as more users start using the system, there are at least 20 occurances in that 20,000 items, so it has to be fixed.

Managed to track down an error in the log

System.Data.SqlClient.SqlException: Transaction (Process ID 61) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

It’s stack trace was similar too this (I cut it down a bit and changed some names, my naming is not this bad)

at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData()
   at Microsoft.SharePoint.SPListItemCollection.get_Item(Guid uniqueId)
   at BinaryJam.Core.Code.TicketListReceiver.ItemReceiver.ItemAddedActual(Guid SiteId, Guid ListItemId, String UserDisplayName)
   at BinaryJam.Core.Code.TicketListReceiver.ItemReceiver.<>c__DisplayClass11.<ItemAdded>b__e()
   at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)
   at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
   at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
   at BinaryJam.Core.Code.ItemListReceiver.ItemReceiver.ItemAdded(SPItemEventProperties properties)

So as you can see, it explodes on the GetItem.

This was my stupid mistake, a mistake I bet many of you are making every day.

SPListItem item = List.Items[listItemId];

This I believe is the primary cause of the problem as this statement loads the complete List before returning the specific item I needed and as this list grows, remember 20,000 items already, its going to get worse.  Now for most of you this won’t be a problem as you will be just getting the ListItem from the parameters, in my case I have to run as elevated as Im doing lots of stuff with Security Groups, that the entering user may not be in, hence my needing to re-get the List Item in the right security context.

So if your having a problem like this remember, Always use the

List.GetItemByID(id); //Or
List.GetItemByUniqueId(guid);

This may or may not solve my problem I believe it will, if it doesn’t it’s still going to improve the performance of my application.  If your wondering, this is the only time I use this and don’t know why I did, the rest of the App uses getby id or SPQueries.

A Good Article on Performance I did actually read, hence the app performs pretty well, except for this one bug, which is now hopefully fixed.

 

 

 

 

Advertisements