none
SPItemEventReceiver update runs n times for one instance RRS feed

  • Question

  • Hello,

    I'm developing a program that overwrites itemadded and itemupdated. All I want to do is to read a field in SQL Server, incrementing this value in the SQL table) and write his value in to an item current's list.After many test, I've detected that sometimes itemupdated is runned multiple times (at the same time: for example , two instances runs in the same second). I use the this.DisableEventFiring() to disable events, but it doesn't work. This is an extract of my code:

            public override void ItemUpdated(SPItemEventProperties properties)
    {
        this.DisableEventFiring();
        string Categoria = srvWeb.getcustomdata(properties.WebUrl, properties.AfterUrl, "Categoria"); // srvWeb is a web service
        string value=getSQLvalue(Categoria); // increment counter associated to Categoria. Return the new counter value
                            srvWeb.SaveDataSystemUpdate(properties.WebUrl, properties.AfterUrl, "Identificador", value); // Save sharepoint list item data. It uses SystemUpdate(false) because I don't want to increment version
                            this.EnableEventFiring();
    }


    When I look the table in the SQL Server I can see that the counter value has been incremented twice. If I do a record of steps in the execution, I see that the update it's executed twice or more for one update.

    Any idea??

    Thanks

    Miquel

    Wednesday, July 16, 2008 2:40 PM

Answers

  • To all,

    It is not unusual for an event to fire more than once from what I've read elsewhere.  For example, in this post: http://www.sharepoint-tips.com/2007/11/why-event-handlers-are-triggered-twice.html the user documents how the ItemUpdated runs twice - once for when the item is Checked-In, and a second time when the item is Saved.  I also read in the "SharePoint Complete Reference 2007" by David Sterling, that he's seen the ItemAdded event run 10 times, and not unusual to see ItemUpdated run twice regularly.  Anyway, I believe this is what you're seeing, probably something considered "by design" if you were to ask MS.

    Kevin
    • Marked as answer by Matt Burnett Friday, January 2, 2009 4:24 PM
    Friday, January 2, 2009 2:43 PM

All replies

  • Change SystemUpdate(false) to UpdateOverwriteVersion().

     

    Wednesday, July 16, 2008 3:32 PM
  • Hello Michael,

     

    I've changed SystemUpdate for UpdateOverwriteVersion. It doesn't work to me. For example, when I upload five documents (one by one) it works for the first three (the sequential number for the documents is correct), but the next one, I'll get the counter incremented with two units (also the document number). Sometimes, the item field is not initialized and I need to edit and save again!!. Then it works ok.  If I upload multiple files at the same time and proceed to edit one by one, the code works ok (for my test). The problem is only when I upload a single file and normally when I repeat the operation three or four times.

     

    Thanks for your answer.

     

    Miquel

    Wednesday, July 16, 2008 3:58 PM
  • Have you placed a break-point in your code and executed it in-process.  Maybe the stack-tace will give you the issue.  The code you have here looks fine.

     

     

    Thursday, July 17, 2008 1:17 AM
  • Hello Shanon,

    Thanks for your answer.

    I've put a break point and it confirms that code executes n times. The problem I think it's (this is the behaivor in debug mode) it runs a first instance of update item, executes 3 or 4 instructions, for example gets the category, and then a second instance is started, simultaneously to the first one and in parallel (in debug mode the instructions runs alternatively). In some cases it works ok because the second instance  find  a correct value in counter and do nothing. Sometimes the value is not yet initialized, but the variable who controls if the value is correct it's initialized.Then, both instances increment my counter.

    Anybody knows, why the event code runs more than one time, and if there'll be a solution to this or this is the normal behavior?

    Thanks for all

    Miquel
    Thursday, July 17, 2008 8:38 AM
  • What is the behavior if you move your code to the ItemUpdate method?

     

    Thursday, July 17, 2008 1:57 PM
  • Hello Shannon,

     

    I've the code in te ItemUpdated event. I can't see any ItemUpdate only ItemUpdating. Can you explain me what event are you refering or what I've to do?

     

    Thanks

     

    Miquel

     

    Thursday, July 17, 2008 2:29 PM
  •  

    Sorry Miquel,

     

    I meant the ItemUpdating event.  My brain was just waking up. Smile

     

    From the actions you are describing, you are updating the contents of your item twice.  It appears you have turned off the events firing with the 'DisableEventFiring'.  It is unclear though what is happening in the three methods you are calling expecially the 'SaveDataSystemUpdate'.

     

    Since you have the ability to use break points, what does your stack trace tell you is the calling line for both calls.  I would image that either the calling code is running twice or there is an update outside of your DisableEventFiring.

     

    If the first is true, then set a break point there and see why this is being executed.  It could be something simple as the placement of the code.

     

    Going back to the previous post.... I would put some code in the ItemUpdating to see how many times that runs as well.  It doesn't have to be fancy.... just something good enough for a break.

     

    The problem is definitly outside the code you provided.

     

     

    Thursday, July 17, 2008 3:02 PM
  • Hello Shanon,

    I've created a ItemUpdating and a break point to this. The code in ItemUpdating does nothing (only to view the calls)

    My manual call stack is:

    Step 1: ItemUpdating (1)
    Step 2: ItemUpdated (1)
    public override void ItemUpdated(SPItemEventProperties properties)
            {
                SPListItem listItem = properties.ListItem;
                string pPrin = "";
                Boolean ModificarLlista = true;   // this instruction causes a new ItemUpdating event

                switch (properties.ListTitle)
                {
                    case ......:
    this.DisableEventFiring(); // the first instuction in the case !!
    Step 3: ItemUpdating (2)
    Step 4: ItemUpdated (1)
     spf.Item.UpdateOverwriteVersion(); // when found this instruction new ItemUpdating event
    Step 5: ItemUpdating (3)
    Step 6: ItemUpdated (2) (new)
    Step 7: ItemUpdated (1)

    ItemUpdated (1) and ItemUpdated (2) run the rest of instructions on an alternative way (in debug mode, I think that when there's no debug, every ItemUpdate runs on his own)

    I can't understand what is happening but is very strange than a Boolean ModificarLlista = true; runs an ItemUpdating event!!


    I don't know if this can be of any help

    Thanks

    Miquel
    Friday, July 18, 2008 1:34 PM
  •  

    Wow....

     

    I am in agreement, I see no reason for the first line to cause an update ....

     

    Boolean ModificarLlista = true;   // this instruction causes a new ItemUpdating event

    What are you using this variable for?  I'm stumped as well.  If you want to share your code I can step through it over the weekend. 

     

     

    Friday, July 18, 2008 3:06 PM
  •  

    Hello Shanon,

     

    I've no inconvenient to share my code. The principal problem is that there're some Sharepoint lists involved, and some sql tables involved, too. I've made a shorter code without sql connections to simplify the program and your test. The function is similar (update code runs many times - I've to stop the process manually!!).

     

    You've to create a document library with title "Calidad" and a hidden column in this library with name "Identificador" (text column). You've to upload a single document, and then initialize the title of the document. Put a breakpoint in your code you can see the differents calls to update and updating event (if there're in your test environment !! )

     

    Thanks

     

    Miquel

     

    Here's the code for update and updating events

     

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Data.SqlClient;

    using System.IO;

    using Microsoft.SharePoint;

    namespace WSSInEvents

    {

     

    public class EventsIn : SPItemEventReceiver

    {

    const string usuariSP = "admIn"; // Credentials user. Used for Web Service

    const string passwordSP = "password";

    const string dominiSP = "domain";

    static SqlConnection sqlcon = null;

    static SqlCommand sqlcom = null;

    public override void ItemUpdating(SPItemEventProperties properties)

    {

    try

    {

    SPListItem listItem = properties.ListItem;

    if (properties.ListTitle == "Calidad")

    {

    }

    }

    catch (Exception e)

    {

    }

    }

     

    public override void ItemUpdated(SPItemEventProperties properties)

    {

    Boolean ModificarLlista = true;

    SPListItem listItem = properties.ListItem;

    string pPrin = "";

    //Boolean ModificarLlista = true;

    switch (properties.ListTitle)

    {

    case "Reevaluación de Proveedores"//NOT RELEVANT FOR US

    try

    {

    pPrin = listItem["Proveedor"].ToString();

    listItem["Proveedores"] = pPrin.Substring(pPrin.LastIndexOf("#") + 1, pPrin.Length - (pPrin.LastIndexOf("#") + 1));

    }

    catch (Exception e)

    {

    }

    break;

    // case ...........

    case "Calidad":

    ModificarLlista = false;

    serveisIn.MyService srvWeb = new WSSInEvents.serveisIn.MyService();

    System.Net.NetworkCredential userCred = new System.Net.NetworkCredential(usuariSP, passwordSP, dominiSP);

    srvWeb.Credentials = userCred;

    try

    {

    this.DisableEventFiring();

    srvWeb.guardarDadesDocSystemUpdate(properties.WebUrl, properties.AfterUrl, "Identificador", "vid");

    this.EnableEventFiring();

    }

    catch

    {

    this.EnableEventFiring();

    }

    break;

    default:

    break;

    }

    try

    {

    if (ModificarLlista)

    {

    this.DisableEventFiring();

    listItem.Update();

    this.EnableEventFiring();

    }

    }

    catch (Exception e)

    {

    }

    }

    }

    }

     

     

    CODE OF WEB SERVICE

     

    using System;

    using System.Web;

    using System.Web.Services;

    using System.Web.Services.Protocols;

    using Microsoft.SharePoint;

    using Microsoft.SharePoint.Library;

    using Microsoft.SharePoint.Metabase;

    using Microsoft.SharePoint.WebControls;

    using System.Data;

    using System.Collections;

    using System.IO;

    /// <summary>

    /// Summary description for MyService

    /// </summary>

    [WebService(Namespace = "http://microsoft.com/mywebservice/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    public class MyService : System.Web.Services.WebService

    {

    public MyService()

    {

    //Uncomment the following line if using designed components

    //InitializeComponent();

    }

     

    [WebMethod]

    public void guardarDadesDocSystemUpdate(string WebURL, string DocURL, string camp, string valor)

    {

    SPSite sps = new SPSite(WebURL);

    SPWeb spw = sps.OpenWeb();

    SPFile spf = spw.GetFile(DocURL);

    spw.AllowUnsafeUpdates = true;

    //if (spf != null) valor = spf.Item[camp].ToString();

    spf.Item[camp] = valor;

    spf.Item.UpdateOverwriteVersion();

    //spf.Item.SystemUpdate(false);

    //spf.Item.Update();

    //spf.Update();

    }

    }

     

    Monday, July 21, 2008 12:31 PM
  • Hello to all,

     

    We're doing new tests. We've found something really strange. When we update the document's properties the code executes only once. The update code runs more than once time when we upload one file and the screen to fill up the document's properties is shown.

     

    Any idea?

     

    Thanks for your help,

     

    Miquel

     

    Monday, July 21, 2008 8:27 PM
  • Updating the metadata is a different update then adding the document.

     

    Why don't you just create a column on the document called "Initialized" and check it in the update.

     

    psuedocode

     

    if(properties.AfterProperties["Initialized"] == false)

    {

        //set other values

        properties.AfterProperties["Initialized"] = true;
    }

    Monday, July 21, 2008 8:31 PM
  • Hello Michael,

     

    Thanks for your response.

     

    We've created a column Initialized like you've suggested. Using properties.AfterProperties["Initialized"] the program give us a null value (I can't full test your code). If we use properties.ListItem.Properties["Initialized"].ToString() we don't get any value (default value for initialized is set to false). If we use properties.ListItem.Properties["Initialized"] to set the value, the program starts a new thread in updated event. It's like DisableEventFiring don't work with a new item !! 

     

     

    Miquel

    Monday, July 21, 2008 10:18 PM
  • To all,

    It is not unusual for an event to fire more than once from what I've read elsewhere.  For example, in this post: http://www.sharepoint-tips.com/2007/11/why-event-handlers-are-triggered-twice.html the user documents how the ItemUpdated runs twice - once for when the item is Checked-In, and a second time when the item is Saved.  I also read in the "SharePoint Complete Reference 2007" by David Sterling, that he's seen the ItemAdded event run 10 times, and not unusual to see ItemUpdated run twice regularly.  Anyway, I believe this is what you're seeing, probably something considered "by design" if you were to ask MS.

    Kevin
    • Marked as answer by Matt Burnett Friday, January 2, 2009 4:24 PM
    Friday, January 2, 2009 2:43 PM