Пример #1
0
        /// <summary>
        /// Increases the total size of the pool by the amount specified.
        /// </summary>
        /// <param name="increaseBy">The amount of values to increase the pool by.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task IncreasePoolSizeAsync(int increaseBy = 1, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (IsDisposed || IsDisposing)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (increaseBy < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(increaseBy));
            }

            for (int i = 0; i < increaseBy; i++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var instance = await Task.Run(() => InstanceBuilder.Invoke(cancellationToken), cancellationToken).ConfigureAwait(false);

                await Task.Run(() =>
                {
                    PooledInstances.Enqueue(instance);
                }, cancellationToken).ConfigureAwait(false);

                Interlocked.Increment(ref _totalInstancesCount);
                RaisePropertyChanged(nameof(TotalInstancesCount));
            }
        }
Пример #2
0
        /// <summary>
        /// Acquires the next available pooled value.
        /// </summary>
        /// <param name="pooledValueAcquisitionMode">The pooled value acquisition mode.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <Pooled <TValue> > AcquirePooledValueAsync(
            PooledValueAcquisitionMode pooledValueAcquisitionMode = PooledValueAcquisitionMode.AvailableInstanceOrDefaultValue,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (IsDisposed || IsDisposing)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            TValue value = default(TValue);

            // check whether we actually currently have any instances left
            if (PooledInstances.IsEmpty)
            {
                if (pooledValueAcquisitionMode == PooledValueAcquisitionMode.AvailableInstanceOrDefaultValue)
                {
                    return(default(Pooled <TValue>));
                }
                else if (pooledValueAcquisitionMode == PooledValueAcquisitionMode.AvailableInstanceOrCreateNewOne)
                {
                    try
                    {
                        value = await Task.Run(() => InstanceBuilder.Invoke(cancellationToken), cancellationToken).ConfigureAwait(false);
                    }
                    catch (TargetInvocationException targetInvocationException)
                    {
                        targetInvocationException.InnerException.ThrowIfNotNull();
                    }
                }
                else
                {
                    while (PooledInstances.IsEmpty || PooledInstances.TryDequeue(out value) == false)
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        await Task.Yield();
                    }
                }
            }
            else
            {
                // try to retrieve the next available / queued value
                if (PooledInstances.TryDequeue(out value) == false)
                {
                    if (pooledValueAcquisitionMode == PooledValueAcquisitionMode.AvailableInstanceOrDefaultValue)
                    {
                        return(default(Pooled <TValue>));
                    }
                    else if (pooledValueAcquisitionMode == PooledValueAcquisitionMode.AvailableInstanceOrCreateNewOne) // build a new one
                    {
                        try
                        {
                            value = await Task.Run(() => InstanceBuilder.Invoke(cancellationToken), cancellationToken).ConfigureAwait(false);
                        }
                        catch (TargetInvocationException targetInvocationException)
                        {
                            targetInvocationException.InnerException.ThrowIfNotNull();
                        }
                    }
                    else
                    {
                        // keep trying
                        while (PooledInstances.TryDequeue(out value) == false)
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            await Task.Yield();
                        }
                    }
                }
            }

            RaisePropertyChanged(nameof(AvailableInstancesCount));
            cancellationToken.ThrowIfCancellationRequested();
            return(new Pooled <TValue>(value, this));
        }