Beispiel #1
0
        /// <summary>
        /// Shuts down all the channel creators.
        /// </summary>
        /// <returns></returns>
        public Task ShutdownAsync()
        {
            _readWriteLock.EnterWriteLock();
            try
            {
                if (_shutdown)
                {
                    _tcsReservationDone.SetException(new TaskFailedException("Already shutting down."));
                    return _tcsReservationDone.Task;
                }
                _shutdown = true;
            }
            finally
            {
                _readWriteLock.ExitWriteLock();
            }

            // Fast shutdown for those that are in the queue is not required.
            // Let the executor finish since the shutdown-flag is set and the
            // future will be set as well to "shutting down".
            
            // .NET-specific: queued tasks cannot be aborted, but the flag indicates
            // the shutdown and the result will be set to failed

            // the channel creator doesn't change anymore from here on
            int size = _channelCreators.Count;
            if (size == 0)
            {
                _tcsReservationDone.SetResult(null);
            }
            else
            {
                var completeCounter = new VolatileInteger(0);
                foreach (var channelCreator in _channelCreators)
                {
                    // It's important to set the listener before calling shutdown.
                    channelCreator.ShutdownTask.ContinueWith(delegate
                    {
                        if (completeCounter.IncrementAndGet() == size)
                        {
                            // we can block here
                            _semaphoreUdp.Acquire(_maxPermitsUdp);
                            _semaphoreTcp.Acquire(_maxPermitsTcp);
                            _semaphorePermanentTcp.Acquire(_maxPermitsPermanentTcp);
                            _tcsReservationDone.SetResult(null);
                        }
                    });
                    channelCreator.ShutdownAsync();
                }
            }
            return _tcsReservationDone.Task;
        }
        public Task ShutdownAsync()
        {
            if (_timer != null)
            {
                // .NET-specific
                ExecutorService.Cancel(_timer);
            }
            var tcsShutdown = new TaskCompletionSource<object>();
            lock (_lock)
            {
                _shutdown = true;
                int max = _runningTasks.Count;
                if (max == 0)
                {
                    tcsShutdown.SetResult(null);
                    return tcsShutdown.Task;
                }
                var counter = new VolatileInteger(0);
                foreach (var task in _runningTasks.Keys)
                {
                    task.ContinueWith(t =>
                    {
                        if (counter.IncrementAndGet() == max)
                        {
                            tcsShutdown.SetResult(null); // complete
                        }
                    });
                }
            }

            return tcsShutdown.Task;
        }