Tuesday, September 28, 2010

This object will now be disposed

Recently we had to process around 2000 items on the list. Basically we needed to fire the update event on every item.
The code looks very simple:
 using (SPSite oSiteCollection = GetSPSite(properties, "http://test/t1/t2/t3"))
            {
                using (SPWeb oWebsite = GetSPWeb(properties, oSiteCollection))
                {
                    bool oldAllowUnsafeUpdates = oWebsite.AllowUnsafeUpdates;
                    oWebsite.AllowUnsafeUpdates = true;
                    try
                    {
                        SPList destSPList = GetListByUrlPattern(oWebsite, "Lists/mylist");
                        if (destSPList != null)
                        {
                            List<SPListItem> tmpList = new List<SPListItem>(destSPList.ItemCount);
                            foreach (SPListItem tmpSpListItem in destSPList.Items)
                                tmpList.Add(tmpSpListItem);
                            tmpList.Sort(delegate(SPListItem op1, SPListItem op2) { return op1.ID.CompareTo(op2.ID); });

                            RTWEventLog.WriteInfo("RTWSMSIncidentPermissionPatch is starting processing!");
                            int incCount = tmpList.Count;
                            for (int i = 0; i < incCount; i++)
                            {
                                SPListItem spListItem = tmpList[i];
                                try
                                {
                                    if (!spListItem.HasUniqueRoleAssignments)
                                    {
                                       
                                        System.Threading.Thread.Sleep(5000);
                                        spListItem.Update();
                                        System.Threading.Thread.Sleep(10000);

                                        RTWEventLog.WriteInfo(string.Format("The Item {0} (ID:{1}) is processed!", spListItem.DisplayName, spListItem.ID));
                                    }
                                }
                                catch (Exception ex)
                                {
                                    RTWEventLog.WriteError(ex);
                                }
                            }
                            RTWEventLog.WriteInfo("RTWSMSIncidentPermissionPatch is completed!");
                        }
                        else
                            throw new ApplicationException("Couldn't find list with url Lists/mylist");
                    }
                    catch (Exception ex)
                    {
                        RTWEventLog.WriteError(ex);
                    }

                    oWebsite.AllowUnsafeUpdates = oldAllowUnsafeUpdates;
                }
            }
        }
We had to put the code in sleep - to be sure that otimer.exe can fetch the event and fires the  handled on the item.
After a while ULS Log shows the error:
An SPRequest object was not disposed before the end of this thread.
 To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as
soon as you are done using it.  This object will now be disposed.  
So the only resume we have  is : don't use a disposable object for too long! Try to dispose and re-create inside your long routine.