Tuesday, June 14, 2011

Delete items from SharePoint list and document libraries


Some days ago I had a problem to delete all items from standard SharePoint list. There are the following possible ways to do it:
  1. Delete list at all and create it once again. This option is very fast but we need to create the list again with all fields, views etc. It is a rounite operation and could take much time. Also it can be item event receiver for delete action that makes some changes. The delete list operation without delete all items may cause some problems depending on the logic in the receiver.
  2. Select all list items and delete it.
Option 2 was more preferable for me. I had a Classes list with timetable for English courses. The list had about 11.000 items and sometimes I had to delete them for my purposes. Also this list had one item event receiver for delete action - to delete classes from classes workspaces. So I've started to implement this solution as console application. The code was very simple - create SPSite, SPWeb objects, find list and select all items using empty SPQuery. After implementation I've started to test my solution. The overall performance was about 50-90 items per minute. I was very surprised but in a short time I've found the problem. The item event receiver execution was too long. In this case the only one way is to delete items from list in threads. I've added a required parameter - number of threads. Each of them delete its portion of list items. After implemenation and testing the overall performance was 2000-3000 items per minute using 15 threads. So the whole delete operation is taking about 3-4 minutes now. This is a good result for me. The following code split all list items to batches for an every thread:

for (int i = 0; i < threadCount; i++)
                   {
                       var itemIds = new List<Guid>();
                       if (i != threadCount - 1)
                       {
                           itemIds.AddRange(
                               (from SPListItem item in items select item.UniqueId)
.Skip(i * batchCount).Take(batchCount));
}
                       else
                       {
                           itemIds.AddRange(
                               (from SPListItem item in items select item.UniqueId)
.Skip(i * batchCount));
}
                       ThreadPool.QueueUserWorkItem(DeleteAllItems, 
                             new ThreadParams {Event = events[i], ItemsIds = itemIds});
                   }
                   WaitHandle.WaitAll(events);
 
The application has 2 required parameters: listUrl and threadCount.
Usage example: clearlist.exe -listUrl http://localhost/sites/project/Lists/Classes/AllItems.aspx -threadCount 10
Link to download Visual Studio Solution

2 comments:

  1. Nice post. It works on my doc library

    ReplyDelete
  2. Works perfectly. Thank you very much

    ReplyDelete