private bool ScheduleSubDirectoryTransfer(
            SubDirectoryTransfer subDirectoryTransfer,
            CancellationToken cancellationToken,
            Action persistDirTransfer,
            int timeOut)
        {
            Interlocked.Increment(ref this.outstandingTasks);
            Task directoryListTask = null;

            try
            {
                directoryListTask = DirectoryListingScheduler.Instance().Schedule(
                    subDirectoryTransfer,
                    cancellationToken,
                    persistDirTransfer,
                    timeOut);
            }
            catch (OperationCanceledException)
            {
                // Ignore exception
            }
            catch (ObjectDisposedException)
            {
                // Ignore exception
            }

            this.WaitOnSubDirectoryListTask(directoryListTask, subDirectoryTransfer);
            return(null != directoryListTask);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (null != this.subDirTransfersCompleteSource)
                {
                    this.subDirTransfersCompleteSource.Task.Wait();
                }

                if (null != this.transfersCompleteSource)
                {
                    this.transfersCompleteSource.Task.Wait();
                }

                if (null != this.cancellationTokenSource)
                {
                    this.cancellationTokenSource.Dispose();
                    this.cancellationTokenSource = null;
                }

                if (null != this.progressUpdateLock)
                {
                    this.progressUpdateLock.Dispose();
                    this.progressUpdateLock = null;
                }

                if (null != this.maxConcurrencyControl)
                {
                    this.maxConcurrencyControl.Dispose();
                    this.maxConcurrencyControl = null;
                }

                if (null != this.newAddSubDirResetEventSlim)
                {
                    this.newAddSubDirResetEventSlim.Dispose();
                    this.newAddSubDirResetEventSlim = null;
                }

                if (null != this.directoryListingScheduler)
                {
                    this.directoryListingScheduler.Dispose();
                    this.directoryListingScheduler = null;
                }

                if (null != this.azureFileDirectorySDDLCache)
                {
                    this.azureFileDirectorySDDLCache.Dispose();
                    this.azureFileDirectorySDDLCache = null;
                }
            }

            base.Dispose(disposing);
        }
        private void ResetExecutionStatus()
        {
            if (null != this.cancellationTokenSource)
            {
                this.cancellationTokenSource.Dispose();
            }

            if (null != this.newAddSubDirResetEventSlim)
            {
                this.newAddSubDirResetEventSlim.Dispose();
            }

            if (null != directoryListingScheduler)
            {
                this.directoryListingScheduler.Dispose();
            }

            this.newAddSubDirResetEventSlim    = new ManualResetEventSlim();
            this.cancellationTokenSource       = new CancellationTokenSource();
            this.transfersCompleteSource       = new TaskCompletionSource <object>();
            this.subDirTransfersCompleteSource = new TaskCompletionSource <object>();

            int maxListingThreadCount = 0;

            if (TransferManager.Configurations.MaxListingConcurrency.HasValue)
            {
                maxListingThreadCount = TransferManager.Configurations.MaxListingConcurrency.Value;
            }
            else
            {
#if DOTNET5_4
                maxListingThreadCount = 6;
#else
                maxListingThreadCount = 2;
#endif

                if ((this.Destination.Type == TransferLocationType.LocalDirectory) || (this.Source.Type == TransferLocationType.LocalDirectory))
                {
#if DOTNET5_4
                    maxListingThreadCount = 4;
#else
                    maxListingThreadCount = 2;
#endif
                }
            }


            directoryListingScheduler = new DirectoryListingScheduler(maxListingThreadCount);
        }
        public static DirectoryListingScheduler Instance()
        {
            if (null == SchedulerInstance)
            {
                lock (SingletonLock)
                {
                    if (null == SchedulerInstance)
                    {
                        SchedulerInstance = new DirectoryListingScheduler();
                    }
                }
            }

            return(SchedulerInstance);
        }