public void Dispose_Wait_Running_Or_Queued_Tasks()
        {
            // arrange
            TestResource testResource = new TestResource();
            SharedResource <TestResource> sharedResource = new SharedResource <TestResource>
                                                           (
                resource: testResource,
                maxConcurrentUserCount: 1,
                isMaxConcurrentUserCountReadOnly: true
                                                           );

            // act
            const int taskCount = 1000;

            Task[] tasks = new Task[taskCount];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = sharedResource.UseAsync(p => p.Resource.IncreaseCounterNoThreadSafe());
            }

            sharedResource.Dispose();
            testResource.WaitUntilDisposedFor5Minutes();

            // assert
            Assert.IsTrue(testResource.IsDisposed);
            Assert.IsTrue(testResource.Counter == taskCount);
        }
        public void Dispose_Ignores_Running_Or_Queued_Tasks_That_Canceled_Or_Faulted()
        {
            // arrange
            TestResource testResource = new TestResource();
            SharedResource <TestResource> sharedResource = new SharedResource <TestResource>
                                                           (
                resource: testResource,
                maxConcurrentUserCount: 1,
                isMaxConcurrentUserCountReadOnly: true
                                                           );

            // act
            const int taskCount = 1000;

            Task[] tasks           = new Task[taskCount];
            int    normalTaskCount = 0;

            for (int i = 0; i < tasks.Length; i++)
            {
                int switchFactor = i % 3;
                if (switchFactor != 0 && switchFactor != 1)
                {
                    normalTaskCount++;
                }

                CancellationTokenSource tokenSource = new CancellationTokenSource();
                tasks[i] = sharedResource.UseAsync(p =>
                {
                    switch (switchFactor)
                    {
                    case 0:
                        throw new InvalidOperationException("Test Exception");

                    case 1:
                        tokenSource.Cancel();
                        tokenSource.Token.ThrowIfCancellationRequested();
                        break;

                    default:
                        p.Resource.IncreaseCounterNoThreadSafe();
                        break;
                    }
                },
                                                   tokenSource.Token);
            }

            sharedResource.Dispose();
            testResource.WaitUntilDisposedFor5Minutes();

            // assert
            Assert.IsTrue(testResource.IsDisposed);
            Assert.IsTrue(testResource.Counter == normalTaskCount);
        }
        public void Dispose_Disposes_Resource()
        {
            // arrange
            TestResource testResource = new TestResource();
            SharedResource <TestResource> sharedResource = new SharedResource <TestResource>
                                                           (
                resource: testResource,
                maxConcurrentUserCount: 1,
                isMaxConcurrentUserCountReadOnly: true
                                                           );

            // act
            Task task = sharedResource.UseAsync(p => p.Resource.IncreaseCounterNoThreadSafe());

            sharedResource.Dispose();
            testResource.WaitUntilDisposedFor5Minutes();

            // assert
            Assert.IsTrue(testResource.IsDisposed);
            Assert.IsTrue(testResource.Counter == 1);
        }