Exemplo n.º 1
0
        /// <summary>
        /// Executes the <see cref="Func{T}"/> provided n times, awaiting for the task to be completed, limiting the
        /// concurrency.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action"></param>
        /// <param name="times"></param>
        /// <param name="limit"></param>
        /// <returns>A Task that can be awaited.</returns>
        public static Task TimesLimit <T>(Func <Task <T> > action, int times, int limit)
        {
            var tcs     = new TaskCompletionSource <bool>();
            var counter = new SendReceiveCounter();

            for (var i = 0; i < limit; i++)
            {
                SendNew(action, tcs, counter, times);
            }
            return(tcs.Task);
        }
Exemplo n.º 2
0
        private static void SendNew <T>(Func <Task <T> > action, TaskCompletionSource <bool> tcs, SendReceiveCounter counter, int maxLength)
        {
            var sendCount = counter.IncrementSent();

            if (sendCount > maxLength)
            {
                return;
            }
            var t1 = action();

            t1.ContinueWith(t =>
            {
                if (t.Exception != null)
                {
                    // ReSharper disable once AssignNullToNotNullAttribute
                    tcs.TrySetException(t.Exception.InnerException);
                    return;
                }
                var received = counter.IncrementReceived();
                if (received == maxLength)
                {
                    tcs.TrySetResult(true);
                    return;
                }
                SendNew(action, tcs, counter, maxLength);
            }, TaskContinuationOptions.ExecuteSynchronously);
        }
Exemplo n.º 3
0
        private static void SendNew <T>(Func <Task <T> > action, TaskCompletionSource <bool> tcs, SendReceiveCounter counter, int maxLength)
        {
            var sendCount = counter.IncrementSent();

            if (sendCount > maxLength)
            {
                return;
            }

            Task.Run(async() =>
            {
                try
                {
                    await action().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                    return;
                }

                var received = counter.IncrementReceived();
                if (received == maxLength)
                {
                    tcs.TrySetResult(true);
                    return;
                }
                SendNew(action, tcs, counter, maxLength);
            }).Forget();
        }