Tuesday, November 17, 2009
Useful SharePoint Designer Activities and SharePoint Designer 2010
Tuesday, September 22, 2009
SharePoint List Query performance gotcha
Below is the code that takes 5 hours to run on a dual core box when run against a list with 5500 items.
1: SPList theList = GetList();
2:
3: List<int> itemIds = new List<int>();
4:
5: foreach(SPListItem item in theList.Items)
6: {
7: itemIds.Add(item.ID);
8: }
9:
10: foreach(int itemId in itemIds)
11: {
12:
13: SPListItem theItem = theList.Items.GetItemById(itemId); //this will cause severe performance issues for large lists
14:
15: }
To fix this issue we need to change the code in line 13 to:
13: SPListItem theItem = theList.GetItemById(itemId);
Now the above code will run in minutes.
I wish MSDN documentation on this topic was more clear. That would save me from putting in a couple of late nights at the office.
Monday, December 3, 2007
Disable event firing in SharePoint when updating a list item outside of an event handler
As you probably know, when developing Event Handlers for SharePoint you have the option turning off event firing. This functionality is exposed through SPEventReceiverBase.DisableEventFiring() Method . This is very useful when you are updating the item from within the event handler and do not want an infinite loop to occur.
During my last project i discovered that you cannot disable event firing from code that is not part of an event handler, because DisableEventFiring() is an internal instance method. Still, i was determined to find a solution. So i whipped out Reflector and started investigating. Upon disassembling Microsoft.Sharepoint.dll, I discovered that the above mentioned method actually sets a static, thread-specific, property of SPEventManager class called EventFiringDisabled. SPEventManager class is responsible for instantiating event handlers and delivering events to them. Because this class is marked "internal", it is not intended for use by SharePoint API consumers . But what is a good solution without some HACKS? :) I used reflection to set EventFiringDisabled property.
Below, you will find my solution neatly wrapped in a class. Please use at your own risk.
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.SharePoint;
/// provides access to the internal Microsoft.SharePoint.SPEventManager class by using reflection
/// sample usage:
/// SPEventManagerWrapper.DisableEventFiring();
/// SPList myList = SPContext.Current.Web.Lists["Shared Documents"];
/// SPEventManagerWrapper.EnableEventFiring();
public static class SPEventManagerWrapper
{
private static readonly string _className = "Microsoft.SharePoint.SPEventManager";
private static readonly string _eventFiringSwitchName = "EventFiringDisabled";
private static Type _eventManagerType;
/// gets the status of event firing on the current thread
public static bool EventFiringDisabled
{
get { return GetEventFiringSwitchValue(); }
}
private static Type EventManagerType
{
get
{
if (_eventManagerType == null)
GetEventManagerType();
return _eventManagerType;
}
}
/// enables event firing on the current thread
public static void EnableEventFiring()
{
SetEventFiringSwitch(false);
}
/// disables sharepoint event firing on the current thread
public static void DisableEventFiring()
{
SetEventFiringSwitch(true);
}
/// sets the event firing switch on Microsoft.SharePoint.SPEventManager class using reflection
private static void SetEventFiringSwitch(bool value)
{
PropertyInfo pi = EventManagerType.GetProperty(_eventFiringSwitchName, System.Reflection.BindingFlags.Static System.Reflection.BindingFlags.NonPublic);
pi.SetValue(null, value, null);
}
private static bool GetEventFiringSwitchValue()
{
PropertyInfo pi = EventManagerType.GetProperty(_eventFiringSwitchName, System.Reflection.BindingFlags.Static System.Reflection.BindingFlags.NonPublic);
object val = pi.GetValue(null, null);
return (bool)val;
}
private static Type GetEventManagerType()
{
_eventManagerType = typeof(SPList).Assembly.GetType(_className, true);
return _eventManagerType;
}
}