public void TestMultipleThreadsAddingAndRemovingCallbacks()
        {
            #region Prepare: add some callbacks first so we have something to delete
            for (int i = 0; i < numberOfTasks; ++i)
            {
                var nonCapturedI = i;
                AID.ApplicationInsights_AddCallbacks(nonCapturedI, () => nonCapturedI, null, null);
            }
            #endregion

            Task[] allTasks = new Task[numberOfTasks * 2];

            for (int i = 0; i < numberOfTasks; ++i)
            {
                int nonCapturedI = i;

                allTasks[nonCapturedI] =
                    Task.Factory.StartNew(
                        () => AID.ApplicationInsights_RemoveCallbacks(nonCapturedI, 0));
                allTasks[nonCapturedI + numberOfTasks] =
                    Task.Factory.StartNew(
                        () => AID.ApplicationInsights_AddCallbacks(nonCapturedI + numberOfTasks, () => nonCapturedI + numberOfTasks, null, null));
            }

            Task.WaitAll(allTasks);

            for (int i = numberOfTasks; i < 2 * numberOfTasks; ++i)
            {
                Assert.AreEqual(i, Convert.ToInt32(AID.ApplicationInsights_OnBegin(i), CultureInfo.InvariantCulture));
            }
        }
        public void TestCleanup()
        {
            AID.ApplicationInsights_RemoveCallbacks(methodId, 0);
            AID.ApplicationInsights_RemoveCallbacks(methodId, 1);

            for (int i = 0; i < numberOfTasks; ++i)
            {
                AID.ApplicationInsights_RemoveCallbacks(i, 0);
            }
        }
        public void ExceptionDoesNotDeadLock()
        {
            AID.ApplicationInsights_AddCallbacks(1, () => 1, null, null);

            try
            {
                AID.ApplicationInsights_AddCallbacks(1, () => 1, null, null);
            }
            catch
            {
            }

            AID.ApplicationInsights_RemoveCallbacks(1, 0); // should not throw concurrency exception
        }