示例#1
0
        /// <summary>
        /// Invoke underlying batch operation with aggregating.
        /// </summary>
        public async Task <IReadOnlyList <TResult> > InvokeAsync(IReadOnlyList <TArg> args)
        {
            ProxyItem <TArg, TResult> proxyItem;
            int startIndex;

            if (!TryAggregate(args, out proxyItem, out startIndex))
            {
                proxyItem = new ProxyItem <TArg, TResult>(args);
                _aggregatableQueue.TryAdd(proxyItem, null);
                startIndex = 0;
                _pool.Queue(async() =>
                {
                    object _;
                    _aggregatableQueue.TryRemove(proxyItem, out _);
                    proxyItem.Close();
                    try
                    {
                        proxyItem.TaskCompletionSource.SetResult(await _func(proxyItem.Args));
                    }
                    catch (Exception ex)
                    {
                        proxyItem.TaskCompletionSource.SetException(ex);
                    }
                });
            }
            var results = await proxyItem.TaskCompletionSource.Task;
            await Task.Yield();

            return((IReadOnlyList <TResult>) new Segment <TResult>(results, startIndex, args.Count));
        }
示例#2
0
        private bool TryAggregate(
            IReadOnlyList <TArg> args,
            out ProxyItem <TArg, TResult> proxyItem,
            out int startIndex)
        {
            foreach (var item in _aggregatableQueue)
            {
                var current = item.Key;
                startIndex = current.TryAggregate(args, _rules);
                if (startIndex != -1)
                {
                    proxyItem = current;
                    return(true);
                }
            }

            // unable to aggregate
            proxyItem  = null;
            startIndex = -1;
            return(false);
        }