示例#1
0
        public void ShouldOnlyRunOnceWhenInvokeConcurrent()
        {
            var key                  = Utility.NewPassword();
            var isFirstTime          = true;
            var actionExecutionCount = 0;
            var locker               = new object();
            var locker2              = new object();

            Mock.Get(lockService).Setup(p => p.Lock(key, key, It.IsAny <TimeSpan>()))
            .ReturnsAsync(() =>
            {
                lock (locker)
                {
                    var isFirst = isFirstTime;
                    isFirstTime = false;
                    return(isFirst);
                }
            });
            var tasks = System.Linq.Enumerable.Range(0, 10).Select(p => lockService.GlobalRunOnce(key, Action)).ToArray();

            Task.WaitAll(tasks);
            int executeActionTaskCount = tasks.Count(p => p.Result);

            Assert.AreEqual(1, executeActionTaskCount);
            Assert.AreEqual(1, actionExecutionCount);

            void Action()
            {
                lock (locker2)
                {
                    Task.Delay(10).Wait();
                    actionExecutionCount++;
                }
            }
        }
        public static async Task GlobalRunOnceOrWaitFor(this ILockService lockService, string key, Action action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            var executed = await lockService.GlobalRunOnce(key, action);

            if (executed == false)
            {
                await lockService.WaitFor(key);
            }
        }