Beispiel #1
0
        /// <summary>
        /// Executes a named action depending on the chosen algorithm. The default behavior can be modified by the
        /// given <see cref="ExclusiveBlockConfiguration"/>.
        /// </summary>
        /// <param name="key">The unique name of the action.</param>
        /// <param name="operationId">Unique identifier of the caller thread, process or appdomain.</param>
        /// <param name="blockType">The algorithm of the exclusive execution.</param>
        /// <param name="config">The configuration of the exclusive execution.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <param name="action">The code block that will be executed exclusively.</param>
        /// <returns>A Task that represents the asynchronous operation.</returns>
        internal static async Task RunAsync(string key, string operationId, ExclusiveBlockType blockType,
                                            ExclusiveBlockConfiguration config, CancellationToken cancellationToken, Func <Task> action)
        {
            config.CancellationToken = cancellationToken;

            var reTryTimeLimit = DateTime.UtcNow.Add(config.WaitTimeout);

            switch (blockType)
            {
            case ExclusiveBlockType.SkipIfLocked:
                using (var exLock = await GetLock(key, operationId, config)
                                    .ConfigureAwait(false))
                {
                    if (exLock.Acquired)
                    {
                        await action();
                    }
                }     // releases the lock
                break;

            case ExclusiveBlockType.WaitForReleased:
                using (var exLock = await GetLock(key, operationId, config)
                                    .ConfigureAwait(false))
                {
                    if (exLock.Acquired)
                    {
                        await action();
                    }
                    else
                    {
                        await WaitForRelease(key, operationId, reTryTimeLimit, config);
                    }
                }     // releases the lock
                break;

            case ExclusiveBlockType.WaitAndAcquire:
                while (true)
                {
                    using (var exLock = await GetLock(key, operationId, config)
                                        .ConfigureAwait(false))
                    {
                        if (exLock.Acquired)
                        {
                            await action();

                            break;
                        }
                    }     // releases the lock

                    await WaitForRelease(key, operationId, reTryTimeLimit, config);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(blockType), blockType, null);
            }
        }
Beispiel #2
0
        private async System.Threading.Tasks.Task Worker(string operationId, ExclusiveBlockType blockType,
                                                         List <string> log, TimeSpan timeout = default)
        {
            var config = new ExclusiveBlockConfiguration
            {
                LockTimeout = TimeSpan.FromSeconds(1),
                PollingTime = TimeSpan.FromSeconds(0.1),
            };

            if (timeout != default)
            {
                config.WaitTimeout = timeout;
            }

            log.Add("before block " + operationId);
            await ExclusiveBlock.RunAsync("MyFeature", operationId, blockType, config, CancellationToken.None, async() =>
            {
                await System.Threading.Tasks.Task.Delay(1500);
                log.Add("in block " + operationId);
            });

            log.Add("after block " + operationId);
        }
Beispiel #3
0
 /// <summary>
 /// Executes a named action depending on the chosen algorithm.
 /// Do not forget to await for the method as this is an asynchronous operation.
 /// </summary>
 /// <param name="key">The unique name of the action.</param>
 /// <param name="operationId">Unique identifier of the caller thread, process or appdomain.</param>
 /// <param name="blockType">The algorithm of the exclusive execution.</param>
 /// <param name="options">ExclusiveBlock options</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 /// <param name="action">The code block that will be executed exclusively.</param>
 /// <returns>A Task that represents the asynchronous operation.</returns>
 /// <exception cref="DataException">The operation causes a database-related error.</exception>
 /// <exception cref="TimeoutException">The exclusive lock was not released within the specified time</exception>
 /// <exception cref="OperationCanceledException">The operation has been cancelled.</exception>
 public static Task RunAsync(string key, string operationId, ExclusiveBlockType blockType, ExclusiveLockOptions options,
                             CancellationToken cancellationToken, Func <Task> action)
 {
     return(RunAsync(key, operationId, blockType, new ExclusiveBlockConfiguration(options), cancellationToken, action));
 }
        private async System.Threading.Tasks.Task Worker(string key, string operationId, ExclusiveBlockType blockType,
                                                         List <string> log, TimeSpan timeout = default)
        {
            var config = new ExclusiveBlockConfiguration
            {
                //LockTimeout = TimeSpan.FromSeconds(1),
                //PollingTime = TimeSpan.FromSeconds(0.1),
                LockTimeout = TimeSpan.FromSeconds(2.5),
                PollingTime = TimeSpan.FromSeconds(1),
            };

            if (timeout != default)
            {
                config.WaitTimeout = timeout;
            }

            Log(log, "before block " + operationId);
            Trace.WriteLine($"SnTrace: TEST: before block {key} #{operationId}");
            await ExclusiveBlock.RunAsync(key, operationId, blockType, config, CancellationToken.None, async() =>
            {
                Log(log, "in block " + operationId);
                //await System.Threading.Tasks.Task.Delay(1500);
                await System.Threading.Tasks.Task.Delay(3000);
                Trace.WriteLine($"SnTrace: TEST: in block {key} #{operationId}");
            });

            Log(log, "after block " + operationId);
            Trace.WriteLine($"SnTrace: TEST: after block {key} #{operationId}");
        }