none
EWS CancelAppointment throws an error sometime RRS feed

  • Question

  • By using ews managed api i ma trying to cancel some appointments form my application. there may be more than 100 appointments to get cancelled and exach cancel operation is being run a seperate thread and each thred is created aftrer every 100 millisecond

    public int CancelAppointment(Appointment apt)
            {
                try
                {
                    apt = Appointment.Bind(service, apt.Id);
                    apt.CancelMeeting("cancel by Stability");
                    return 1;
                }
                catch (Exception ex)
                {
                    logger.Error("Error : CancelAppointment : " + ex.Message);
                    logger.Error("Source: " + ex.Source);
                    logger.Error("StackTrace: " + ex.StackTrace);
                    return 0;
                }
            }

    Now occasionally for some appointemnt i get following error

    CancelAppointment : The operation can't be performed because the item is out of date. Reload the item and try again.

    i can not make any sense why i am getting this.

    Thanks

    Nitin

    Wednesday, December 7, 2016 5:47 PM

All replies

  • >> The operation can't be performed because the item is out of date

    That means the change key of the underlying item has changed and the version your trying to cancel is out of date (hence the business logic stop you doing something that would result in a poor outcome). If you want to debug it check the ChangeKey that is returned when you bind and then if you get an error try to rebind to the appointment an see if the changekey has been modified. It sounds like you have multiple clients make changes simultaneously. Also is this a recurring appointment if you try to cancel two instances (even if they are separate) of the same recurring appointment that would be a problem because you modifying the same master instance.

    Thursday, December 8, 2016 1:34 AM
  • HI Glen,

    Many Thanks for your reply.

    All are single appointments and there are 100 of appointments and there is a loop for processing these appointments and each counter is creating anew task for canceling each appointment and there is a delay of 100ms for each new task to start.

    here is my code

    public CancelSingleBookingHandler(ConcurrentQueue<Appointment> AptQueue)
            {
                List<System.Threading.Tasks.Task> cancelAppointmentTaskList = new List<System.Threading.Tasks.Task>();
                int count = AptQueue.Count;
                Appointment tmp = null;
                DateTime startTimeStamp = DateTime.UtcNow;
                while (!AptQueue.IsEmpty)
                {
                    System.Threading.Tasks.Task NewTask = System.Threading.Tasks.Task.Factory.StartNew((obj) =>
                    {
                        var paramsArr = (object[])obj;
                        cancelSingleAppointmentConsumer((Appointment)paramsArr[0]);
                        Thread.Sleep(Settings.BookingInterval);
                    }, new object[] { AptQueue.TryDequeue(out tmp) ? tmp : null });
                    cancelAppointmentTaskList.Add(NewTask);
                }
                System.Threading.Tasks.Task.WaitAll(cancelAppointmentTaskList.ToArray());
                CheckCancellingBookings();
                DateTime endTimeStamp = DateTime.UtcNow;
                TimeSpan diff = endTimeStamp - startTimeStamp;
                logger.Info("time to process " + count + " cancel bookings:" + diff.TotalSeconds);
            }

            private void cancelSingleAppointmentConsumer(Appointment apt)
            {
                EWSManager oEWSManager = new EWSManager(1, Settings.ExchangeMethod, Settings.ServiceAccountUserName,
                        Settings.ServiceAccountPassword, "", Settings.ServiceAccountEmail, apt.Organizer.Address, Settings.ExchangeURL,
                        Settings.MSSAPIURL, "", "", Settings.SiteMailBox);
                oEWSManager.CancelAppointment(apt);
            }

    public int CancelAppointment(Appointment apt)
            {
                try
                {
                    apt = Appointment.Bind(service, apt.Id);
                    apt.CancelMeeting("cancel by Stability_Testing_O365_Single");
                    return 1;
                }
                catch (Exception ex)
                {
                    logger.Error("Error : CancelAppointment : " + ex.Message);
                    logger.Error("Source: " + ex.Source);
                    logger.Error("StackTrace: " + ex.StackTrace);
                    return 0;
                }
            }

    let me know if i am doing something wrong here

    Thanks

    Thursday, December 8, 2016 10:47 AM
  • Why don't you just Batch the 100 cancelations in one request (or possible smaller batches) ? the server will then process them in a serial fashion if they are all in the same mailbox that would be a better way to go about it and should perform better also.

    Cheers
    Glen

    Tuesday, December 13, 2016 4:48 AM