コード例 #1
0
        private Task DispatchBatchAsync()
        {
            return(_sync.LockAsync(
                       () => !_buffer.IsEmpty,
                       async() =>
            {
                TaskCompletionBuffer <TKey, TValue> copy =
                    CopyAndClearBuffer();
                TKey[] resolvedKeys = copy.Keys.ToArray();

                if (_options.MaxBatchSize > 0 &&
                    copy.Count > _options.MaxBatchSize)
                {
                    var chunkSize = (int)Math.Ceiling(
                        (decimal)copy.Count / _options.MaxBatchSize);

                    for (var i = 0; i < chunkSize; i++)
                    {
                        TKey[] chunkedKeys = resolvedKeys
                                             .Skip(i * _options.MaxBatchSize)
                                             .Take(_options.MaxBatchSize)
                                             .ToArray();

                        await FetchInternalAsync(copy, chunkedKeys)
                        .ConfigureAwait(false);
                    }
                }
                else
                {
                    await FetchInternalAsync(copy, resolvedKeys)
                    .ConfigureAwait(false);
                }
            }));
        }
コード例 #2
0
        private TaskCompletionBuffer <TKey, TValue> CopyAndClearBuffer()
        {
            TaskCompletionBuffer <TKey, TValue> copy = _buffer;

            _buffer = new TaskCompletionBuffer <TKey, TValue>();

            return(copy);
        }
コード例 #3
0
        private Task DispatchBatchAsync(CancellationToken cancellationToken)
        {
            if (!_buffer.IsEmpty)
            {
                lock (_sync)
                {
                    if (!_buffer.IsEmpty)
                    {
                        Func <Task> execute = async() =>
                        {
                            TaskCompletionBuffer <TKey, TValue> copy =
                                CopyAndClearBuffer();
                            TKey[] keys = copy.Keys.ToArray();

                            if (_options.MaxBatchSize > 0 &&
                                copy.Count > _options.MaxBatchSize)
                            {
                                // splits items from buffer into chunks and instead of
                                // sending the complete buffer, it sends chunk by chunk
                                var chunkSize = (int)Math.Ceiling(
                                    (decimal)copy.Count / _options.MaxBatchSize);

                                for (var i = 0; i < chunkSize; i++)
                                {
                                    TKey[] chunkedKeys = keys
                                                         .Skip(i * _options.MaxBatchSize)
                                                         .Take(_options.MaxBatchSize)
                                                         .ToArray();

                                    await FetchInternalAsync(
                                        copy,
                                        chunkedKeys,
                                        cancellationToken)
                                    .ConfigureAwait(false);
                                }
                            }
                            else
                            {
                                // sends all items from the buffer in one batch
                                // operation
                                await FetchInternalAsync(
                                    copy,
                                    keys,
                                    cancellationToken)
                                .ConfigureAwait(false);
                            }
                        };

                        return(execute());
                    }
                }
            }

            return(Task.CompletedTask);
        }
コード例 #4
0
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="DataLoaderBase{TKey, TValue}"/> class.
        /// </summary>
        /// <param name="options">
        /// A configuration for <c>DataLoaders</c>.
        /// </param>
        /// <param name="cache">
        /// A cache instance for <c>Tasks</c>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Throws if <paramref name="options"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Throws if <paramref name="cache"/> is <c>null</c>.
        /// </exception>
        protected DataLoaderBase(DataLoaderOptions <TKey> options, ITaskCache <TValue> cache)
        {
            _options = options ??
                       throw new ArgumentNullException(nameof(options));
            _buffer           = new TaskCompletionBuffer <TKey, TValue>();
            _cache            = cache ?? throw new ArgumentNullException(nameof(cache));
            _cacheKeyResolver = _options.CacheKeyResolver ??
                                ((TKey key) => key);

            StartAsyncBackgroundDispatching();
        }
コード例 #5
0
        /// <inheritdoc/>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    Clear();
                    _disposeTokenSource.Cancel();
                    _delaySignal?.Set();
                    (_cache as IDisposable).Dispose();
                    _disposeTokenSource.Dispose();
                    _delaySignal?.Dispose();
                }

                _buffer      = null;
                _cache       = null;
                _delaySignal = null;
                _options     = null;

                _disposed = true;
            }
        }
コード例 #6
0
 public void IterationSetup()
 {
     _buffer = new TaskCompletionBuffer <string, int>();
 }