public async Task CanPostManyEvents() {
            await ResetAsync();

            const int batchSize = 250;
            const int batchCount = 10;

            try {
                var countdown = new AsyncCountdownEvent(batchCount);
                var messageSubscriber = IoC.GetInstance<IMessageSubscriber>();
                messageSubscriber.Subscribe<EntityChanged>(ch => {
                    if (ch.ChangeType != ChangeType.Added || ch.Type != typeof(PersistentEvent).Name)
                        return;

                    if (countdown.CurrentCount >= batchCount)
                        throw new ApplicationException("Too many change notifications.");

                    countdown.Signal();
                });

                await Run.InParallel(batchCount, async i => {
                    _eventController.Request = CreateRequestMessage(new ClaimsPrincipal(new User { EmailAddress = TestConstants.UserEmail, Id = TestConstants.UserId, OrganizationIds = new[] { TestConstants.OrganizationId }, Roles = new[] { AuthorizationRoles.Client } }.ToIdentity(TestConstants.ProjectId)), true, false);
                    var events = new RandomEventGenerator().Generate(batchSize);
                    var compressedEvents = await Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(events)).CompressAsync();
                    var actionResult = await _eventController.PostAsync(compressedEvents, version: 2, userAgent: "exceptionless/2.0.0.0");
                    Assert.IsType<StatusCodeResult>(actionResult);
                });

                Assert.Equal(batchCount, (await _eventQueue.GetQueueStatsAsync()).Enqueued);
                Assert.Equal(0, (await _eventQueue.GetQueueStatsAsync()).Completed);

                var processEventsJob = IoC.GetInstance<EventPostsJob>();
                var sw = Stopwatch.StartNew();
                await processEventsJob.RunUntilEmptyAsync();
                sw.Stop();
                Trace.WriteLine(sw.Elapsed);

                Assert.Equal(batchCount, (await _eventQueue.GetQueueStatsAsync()).Completed);
                Assert.Equal(batchSize * batchCount, await EventCountAsync());
                //await countdown.WaitAsync();
            } finally {
                await _eventQueue.DeleteQueueAsync();
            }
        }
        public async Task CanPostManyEventsAsync() {
            await ResetAsync();

            const int batchSize = 250;
            const int batchCount = 10;

            try {
                await Run.InParallelAsync(batchCount, async i => {
                    _eventController.Request = CreateRequestMessage(new ClaimsPrincipal(new User { EmailAddress = TestConstants.UserEmail, Id = TestConstants.UserId, OrganizationIds = new[] { TestConstants.OrganizationId }, Roles = new[] { AuthorizationRoles.Client } }.ToIdentity(TestConstants.ProjectId)), true, false);
                    var events = new RandomEventGenerator().Generate(batchSize);
                    var compressedEvents = await Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(events)).CompressAsync();
                    var actionResult = await _eventController.PostAsync(compressedEvents, version: 2, userAgent: "exceptionless/2.0.0.0");
                    Assert.IsType<StatusCodeResult>(actionResult);
                });

                await _client.RefreshAsync();
                Assert.Equal(batchCount, (await _eventQueue.GetQueueStatsAsync()).Enqueued);
                Assert.Equal(0, (await _eventQueue.GetQueueStatsAsync()).Completed);

                var processEventsJob = IoC.GetInstance<EventPostsJob>();
                var sw = Stopwatch.StartNew();
                await processEventsJob.RunUntilEmptyAsync();
                sw.Stop();
                Trace.WriteLine(sw.Elapsed);

                await _client.RefreshAsync();
                var stats = await _eventQueue.GetQueueStatsAsync();
                Assert.Equal(batchCount, stats.Completed);
                var minimum = batchSize * batchCount;
                Assert.InRange(await EventCountAsync(), minimum, minimum * 2);
            } finally {
                await _eventQueue.DeleteQueueAsync();
            }
        }
        public void CanPostManyEvents() {
            _eventQueue.DeleteQueue();
            RemoveAllEvents();

            const int batchSize = 250;
            const int batchCount = 10;

            try {
                var countdown = new CountDownLatch(10);
                var messageSubscriber = IoC.GetInstance<IMessageSubscriber>();
                messageSubscriber.Subscribe<EntityChanged>(ch => {
                    if (ch.ChangeType != ChangeType.Added || ch.Type != typeof(PersistentEvent).Name)
                        return;

                    if (countdown.Remaining <= 0)
                        throw new ApplicationException("Too many change notifications.");

                    countdown.Signal();
                });

                Parallel.For(0, batchCount, i => {
                    _eventController.Request = CreateRequestMessage(new ClaimsPrincipal(IdentityUtils.CreateUserIdentity(TestConstants.UserEmail, TestConstants.UserId, new[] { TestConstants.OrganizationId }, new[] { AuthorizationRoles.Client }, TestConstants.ProjectId)), true, false);
                    var events = new RandomEventGenerator().Generate(batchSize);
                    var compressedEvents = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(events)).CompressAsync().Result;
                    var actionResult = _eventController.PostAsync(compressedEvents, version: 2, userAgent: "exceptionless/2.0.0.0").Result;
                    Assert.IsType<StatusCodeResult>(actionResult);
                });

                Assert.Equal(batchCount, _eventQueue.GetQueueCount());

                var sw = new Stopwatch();
                var processEventsJob = IoC.GetInstance<EventPostsJob>();
                sw.Start();
                processEventsJob.RunUntilEmpty();
                sw.Stop();
                Trace.WriteLine(sw.Elapsed);

                Assert.Equal(0, _eventQueue.GetQueueCount());
                Assert.Equal(batchSize * batchCount, EventCount());

                bool success = countdown.Wait(5000);
                Assert.True(success);
            } finally {
                _eventQueue.DeleteQueue();
            }
        }