/// <summary>
        /// Creates a new job schedule.
        /// </summary>
        /// <param name="parameters">The parameters to use when creating the job schedule.</param>
        public void CreateJobSchedule(NewJobScheduleParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            JobScheduleOperations jobScheduleOperations = parameters.Context.BatchOMClient.JobScheduleOperations;
            CloudJobSchedule      jobSchedule           = jobScheduleOperations.CreateJobSchedule();

            jobSchedule.Id          = parameters.JobScheduleId;
            jobSchedule.DisplayName = parameters.DisplayName;

            if (parameters.Schedule != null)
            {
                jobSchedule.Schedule = parameters.Schedule.omObject;
            }

            if (parameters.JobSpecification != null)
            {
                Utils.Utils.JobSpecificationSyncCollections(parameters.JobSpecification);
                jobSchedule.JobSpecification = parameters.JobSpecification.omObject;
            }

            if (parameters.Metadata != null)
            {
                jobSchedule.Metadata = new List <MetadataItem>();
                foreach (DictionaryEntry d in parameters.Metadata)
                {
                    MetadataItem metadata = new MetadataItem(d.Key.ToString(), d.Value.ToString());
                    jobSchedule.Metadata.Add(metadata);
                }
            }
            WriteVerbose(string.Format(Resources.CreatingJobSchedule, parameters.JobScheduleId));
            jobSchedule.Commit(parameters.AdditionalBehaviors);
        }
        public void Bug1910530_ConcurrentChangeTrackedListThreadsafeTest()
        {
            const string testName = "Bug1910530_ConcurrentChangeTrackedListThreadsafeTest";

            using (BatchClient batchCli = ClientUnitTestCommon.CreateDummyClient())
            {
                JobScheduleOperations jobScheduleOperations = batchCli.JobScheduleOperations;

                string jobScheduleId = Microsoft.Azure.Batch.Constants.DefaultConveniencePrefix + "-" + testName;

                //
                //Unbound job schedule properties
                //
                this.testOutputHelper.WriteLine("Creating job schedule {0}", jobScheduleId);
                CloudJobSchedule unboundJobSchedule = jobScheduleOperations.CreateJobSchedule(jobScheduleId, null, null);

                //Create a new threadsafe collection
                unboundJobSchedule.Metadata = new List <MetadataItem>();

                //Now it should be magically threadsafe
                Action addAction = () =>
                {
                    this.testOutputHelper.WriteLine("Adding an item");
                    unboundJobSchedule.Metadata.Add(new MetadataItem("test", "test"));
                };

                Action removeAction = () =>
                {
                    this.testOutputHelper.WriteLine("Removing an item");
                    try
                    {
                        unboundJobSchedule.Metadata.RemoveAt(0);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                    }
                };

                Random rand     = new Random();
                object randLock = new object();

                Parallel.For(0, 100, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = 10
                }, (i) =>
                {
                    int randomInt;
                    lock (randLock)
                    {
                        randomInt = rand.Next(0, 2);
                    }

                    if (randomInt == 0)
                    {
                        addAction();
                    }
                    else
                    {
                        removeAction();
                    }
                });
            }
        }