Exemple #1
0
        private static async Task ZAwaitAll(cMethodControl pMC, IEnumerable <Task> pTasks)
        {
            List <Task> lTasks = new List <Task>();

            foreach (var lTask in pTasks)
            {
                if (lTask != null)
                {
                    lTasks.Add(lTask);
                }
            }

            if (lTasks.Count == 0)
            {
                return;
            }

            using (var lAwaiter = new cAwaiter(pMC))
            {
                Task lCompleted = await Task.WhenAny(lAwaiter.mTask, Task.WhenAll(lTasks)).ConfigureAwait(false);

                if (ReferenceEquals(lCompleted, lAwaiter.mTask))
                {
                    if (lAwaiter.mTask.IsCanceled)
                    {
                        throw new OperationCanceledException();
                    }
                    throw new TimeoutException();
                }

                List <Exception> lExceptions = new List <Exception>();

                foreach (var lTask in lTasks)
                {
                    if (lTask.Exception != null)
                    {
                        lExceptions.AddRange(lTask.Exception.Flatten().InnerExceptions);
                    }
                    else if (lTask.IsCanceled)
                    {
                        lExceptions.Add(new OperationCanceledException());
                    }
                }

                if (lExceptions.Count == 0)
                {
                    return;
                }
                if (lExceptions.Count == 1)
                {
                    throw lExceptions[0];
                }
                throw new AggregateException(lExceptions);
            }
        }
Exemple #2
0
        /// <summary>
        /// Gets a disposable object that represents a block on the granting of exclusive access.
        /// This method will not complete until the block is issued or it throws due to <see cref="cMethodControl"/>.
        /// Dispose the returned object to release the block.
        /// </summary>
        /// <param name="pMC">Controls the execution of the method.</param>
        /// <param name="pParentContext">Context for trace messages.</param>
        /// <returns></returns>
        public async Task <cBlock> GetBlockAsync(cMethodControl pMC, cTrace.cContext pParentContext)
        {
            var lContext = pParentContext.NewMethod(nameof(cExclusiveAccess), nameof(GetBlockAsync), mName, mInstance);

            if (mDisposed)
            {
                throw new ObjectDisposedException(nameof(cExclusiveAccess));
            }

            if (!await mExclusiveSemaphoreSlim.WaitAsync(pMC.Timeout, pMC.CancellationToken).ConfigureAwait(false))
            {
                throw new TimeoutException();
            }
            Interlocked.Increment(ref mBlocks);
            mExclusiveSemaphoreSlim.Release();

            return(new cBlock(mName, mSequence, mInstance, ZReleaseBlock, pParentContext));
        }
Exemple #3
0
        /// <summary>
        /// Gets a disposable object that represents a grant of exclusive access.
        /// This method will not complete until the exclusive access is granted or it throws due to <see cref="cMethodControl"/>.
        /// Dispose the object to release the exclusive access.
        /// </summary>
        /// <param name="pMC">Controls the execution of the method.</param>
        /// <param name="pParentContext">Context for trace messages.</param>
        /// <returns></returns>
        public async Task <cToken> GetTokenAsync(cMethodControl pMC, cTrace.cContext pParentContext)
        {
            var lContext = pParentContext.NewMethod(nameof(cExclusiveAccess), nameof(GetTokenAsync), mName, mInstance);

            if (mDisposed)
            {
                throw new ObjectDisposedException(nameof(cExclusiveAccess));
            }
            if (!await mExclusiveSemaphoreSlim.WaitAsync(pMC.Timeout, pMC.CancellationToken).ConfigureAwait(false))
            {
                throw new TimeoutException();
            }
            while (mBlocks > 0)
            {
                if (!await mBlockCheckSemaphoreSlim.WaitAsync(pMC.Timeout, pMC.CancellationToken).ConfigureAwait(false))
                {
                    throw new TimeoutException();
                }
            }
            mToken = new cToken(mName, mSequence, mInstance, ZReleaseToken, pParentContext);
            return(mToken);
        }
Exemple #4
0
 /// <summary>
 /// Initialises a new instance with the specified method control.
 /// </summary>
 /// <param name="pMC"></param>
 /// <remarks>If a timeout is specified then it runs from when the instance is created.</remarks>
 public cAwaiter(cMethodControl pMC)
 {
     mLinkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(mDisposeCancellationTokenSource.Token, pMC.CancellationToken);
     mTask = Task.Delay(pMC.Timeout, mLinkedCancellationTokenSource.Token);
 }
Exemple #5
0
 /// <inheritdoc cref="AwaitAll(cMethodControl, Task[])"/>
 public static Task AwaitAll(cMethodControl pMC, IEnumerable <Task> pTasks) => ZAwaitAll(pMC, pTasks);
Exemple #6
0
 /// <summary>
 /// Returns a task that completes when all of the passed tasks complete OR when the <see cref="cMethodControl"/> indicates timeout or cancellation.
 /// </summary>
 /// <param name="pMC"></param>
 /// <param name="pTasks">The set of tasks to wait for. Tasks in the set can be <see langword="null"/>.</param>
 /// <returns></returns>
 /// <remarks>
 /// If any of the passed tasks fail (times-out, was cancelled, or throws) then this method throws.
 /// If the <see cref="cMethodControl"/> indicates timeout or cancellation before all the tasks complete then this method throws.
 /// </remarks>
 public static Task AwaitAll(cMethodControl pMC, params Task[] pTasks) => ZAwaitAll(pMC, pTasks);