Long Running Operations within an Event Handler


So, often times when you have an event handler you have to do something that takes longer to execute than SharePoint normally allows for within an event handler. Now normal multi-threading sometimes works here, but often times also runs in to the issue where SharePoint terminates the event as timed out. So here’s a trick I’ve found that works.

You may be familiar with the UI long running job class: Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob this is what generates the page you get for long running operations with the progress bar. However, this same class can be used within your event handler to pass off your long running event operation into a site collection job.

In the below example you can see I just pass the event directly in to a LongRunningOperationJob with an extended time out of 30 minutes. This can go up to 24 hours in my testing reliably. Additionally, this gives you the option to have UI on top of some events from a custom monitoring web part or administrative web part without any more work! YAY!

Example Code:

class ItemEvent : SPItemEventReceiver

{//on item deletion

public override void ItemDeleting(SPItemEventProperties properties)

{

base.ItemDeleting(properties);

DeleteRule longRunningRules = new DeleteRule(properties.ListItem);

longRunningRules.MillisecondsToWaitForFinish = 180000;

longRunningRules.Start(properties.ListItem.Web);

}

}

public class DeleteRule : LongRunningOperationJob

{

private SPListItem rule;

public DeleteRule(SPListItem item)

{

rule = item;

}

public override void DoWork()

{

ItemEvent deleteRule = new ItemEvent();

try

{

deleteRule.deleteItem(rule, true);

}

catch (Exception ex)

{

this.SetError(ex);

}

}

}

  1. #1 by J Turner on April 21, 2011 - 8:21 am

    This was great, thanks for the post. When I looked up the number of miliseconds in 5 minutes it came to 300000… I think maybe you’re text said 30 minutes but you meant 3 minutes.

    • #2 by Maarten on April 21, 2011 - 9:22 am

      You’re absolutely correct :) 3 minutes is what I meant to write

  2. #3 by Essentie on November 15, 2011 - 3:37 am

    Thanx for the post, but what is the method deleteRule.deleteItem(rule, true)?

    • #4 by Maarten on November 16, 2011 - 9:35 am

      That is my function that is being executed when the long running job is started.

      so it goes EventHandler -> LongRunningJob -> your long running code

  3. #5 by ilker on February 24, 2012 - 5:39 am

    Thanks for the great tip, i think it’s more usefull and can used instead of some small workflows that takes a few minutes.

  4. #6 by guru on February 19, 2013 - 9:03 am

    if my ItemAdded event taking 3 hours to complete execution.. can i use this code? how to use this/?
    acually excel sheet will be added as attachment. i have lot of things to do with the sheet, creating items in another list reading excel, it takes more than 3 hours.. can i use your code?

    • #7 by Maarten on February 19, 2013 - 10:10 am

      You could, but if your code is taking 3 hours to execute it points to deeper issues. I’d probably look at alternatives like these:

      Can you optimize your code? Run some tests to see what in your code is taking so long
      Is it a server side performance issue? If so you can look at moving your code to a timer job and running it on an app server instead of a WFE. Or add more RAM, better CPU, etc.
      Would you be better served by using different methods than an event handler? Often times the answer is yes, especially on ItemAdded/Updated events as it’s so easy to replace it with a workflow.

      Basically, go ahead and use this, it won’t make it run faster but your code won’t time out anymore. If I was you I would be looking at figuring out the bottlenecks and fixing those though. Three hours is a long time to be executing and indicates deep seated scalability issues.

      • #8 by guru on February 19, 2013 - 10:17 am

        yes.. it depends on the excel sheets records,
        15K , i m just looping in a for loop and creating batch insert xml, meanwhile i m checking 3 people picker whether they are exists in AD or not. the list has 150 columns and 3 people picker,
        if i use workflow.. if IISreset happens.. does my code continues to work? from where it left? in case of event…it may die i guess
        also web.processbatchdata() i m sending 2000 records and putting in thread. there it was taking time..
        for loop i cant reduce.. it checks duplicates records combines into a single list item.. tell me the best way,, the code has to execute.. it should not die.. workflow or timer job? how can i pass my excel sheet to timer job.

        • #9 by Maarten on February 19, 2013 - 10:23 am

          Timer job 100% the way to go, gives you two advantages here first it is not affected by IISRESET second you can specify which server in the farm to run it on so you’re not getting contention. Also probably faster to do SPList.GetItems(SPQuery).GetDataTable() then using LINQ on the datatable to determine uniqueness.

          Why does the full process need to execute every time an item is added? You could just use the columns of the one list item to query the excel sheet and process 1 item instead of over 2k. Or store the batch insert xml and reference it when you’re checking so you’re not duplicating a ton of work. That way you still maintain uniqueness but your workload doesn’t compound on itself overtime.

          • #10 by guru on February 19, 2013 - 10:29 am

            actually every year. they upload survey excel sheet for, that im uploading it as an attachment to a list. on that list i added itemadded event. which in turn reads the excel sheet and loops all the records in that
            for example
            i have datatable
            Empid SN1 model1 country state
            100 aaa adc india sa
            100 bbb dsdf india sa
            101 ccc sss india ba
            103 ddd sss india sb
            103 eee sds india sb
            103 fff sds india sb

            maximum per employee i can have 15 rows.
            i want a data table like below

            empid country state sn1 model1 sn2 model2 sn3 model3 ……. max sn15 model15
            100 india sa aaa adc bbb dsdf
            101 india ccc
            103 india sb ddd sss eee sds fff sds

  5. #11 by Maarten on February 19, 2013 - 10:32 am

    If it’s once a year then just stick it in to a long running job. Just have them upload it at a non-peak time and tell them it will be done by the morning.

  6. #15 by mandar on April 23, 2014 - 3:35 am

    how can i redirect to sharepoint error page.
    in other words, set navigatewhendoneurl dynamically if errors needs to be reported.

    currently if error is reported,it takes it back where it came from

(will not be published)


%d bloggers like this: