Ejemplo n.º 1
0
        public async Task ShouldNotRepeatTasks()
        {
            //Arrange
            var logs            = new List <Log>();
            var numTasksRunning = 0;
            var taskCompletions = Enumerable
                                  .Range(start: 1, count: 10)
                                  .Select(i => new TaskCompletionSource <int>())
                                  .ToList();
            Func <int, Task> addLog = async taskId =>
            {
                numTasksRunning++;
                logs.Add(new Log {
                    Id = taskId, NumTasksRunning = numTasksRunning
                });
                await taskCompletions[taskId - 1].Task;
                numTasksRunning--;
            };

            var tasks = new List <Func <Task> >
            {
                async() => await addLog(3),
                async() => await addLog(2),
                async() => await addLog(7),
                async() => await addLog(4),
                async() => await addLog(1),
                async() => await addLog(5),
                async() => await addLog(8),
                async() => await addLog(9),
                async() => await addLog(6),
                async() => await addLog(10)
            };

            //Act
            int maxConcurrency  = 3;
            var whenAllComplete = ConcurrentTask.WhenAll(tasks, maxConcurrency);

            taskCompletions.ForEach(taskCompletion => taskCompletion.SetResult(0));
            await whenAllComplete;

            //Assert
            var repeats = logs
                          .Select(log => new { Id = log.Id, Count = logs.Count(l => l.Id == log.Id) })
                          .Where(result => result.Count > 1)
                          .ToList();

            repeats.Count.Should().Be(0, because: $"there should be no repeats but: {string.Join(", ", repeats.Select(repeat => $"(Id: {repeat.Id}, Count: {repeat.Count})"))}.");
        }
Ejemplo n.º 2
0
        public async Task ShouldLimitConcurrency()
        {
            //Arrange
            var logs            = new List <Log>();
            var numTasksRunning = 0;
            var taskCompletions = Enumerable
                                  .Range(start: 1, count: 10)
                                  .Select(i => new TaskCompletionSource <int>())
                                  .ToList();
            Func <int, Task> addLog = async taskId =>
            {
                numTasksRunning++;
                logs.Add(new Log {
                    Id = taskId, NumTasksRunning = numTasksRunning
                });
                await taskCompletions[taskId - 1].Task;
                numTasksRunning--;
            };

            var tasks = new List <Func <Task> >
            {
                async() => await addLog(1),
                async() => await addLog(4),
                async() => await addLog(6),
                async() => await addLog(3),
                async() => await addLog(5),
                async() => await addLog(7),
                async() => await addLog(2),
                async() => await addLog(9),
                async() => await addLog(10),
                async() => await addLog(8)
            };

            //Act
            int maxConcurrency  = 3;
            var whenAllComplete = ConcurrentTask.WhenAll(tasks, maxConcurrency);

            taskCompletions.ForEach(taskCompletion => taskCompletion.SetResult(0));
            await whenAllComplete;

            //Assert
            logs
            .Max(log => log.NumTasksRunning)
            .Should()
            .Be(maxConcurrency, because: $"there should be up to {maxConcurrency} tasks in flight.");
        }
        public async Task ShouldLimitConcurrency()
        {
            //Arrange
            var numTasksRunning = 0;
            var taskCompletions = Enumerable
                                  .Range(start: 1, count: 10)
                                  .Select(i => new TaskCompletionSource <int>())
                                  .ToList();
            Func <int, Task <int> > resultFromTaskId = async taskId =>
            {
                numTasksRunning++;
                var   taskCount = numTasksRunning;
                await taskCompletions[taskId - 1].Task;
                numTasksRunning--;

                return(taskCount);
            };

            var tasks = new List <Func <Task <int> > >
            {
                async() => await resultFromTaskId(1),
                async() => await resultFromTaskId(4),
                async() => await resultFromTaskId(6),
                async() => await resultFromTaskId(3),
                async() => await resultFromTaskId(5),
                async() => await resultFromTaskId(7),
                async() => await resultFromTaskId(2),
                async() => await resultFromTaskId(9),
                async() => await resultFromTaskId(10),
                async() => await resultFromTaskId(8)
            };

            //Act
            int maxConcurrency = 3;
            var getTaskCounts  = ConcurrentTask.WhenAll(tasks, maxConcurrency);

            taskCompletions.ForEach(taskCompletion => taskCompletion.SetResult(0));
            var taskCounts = await getTaskCounts;

            //Assert
            taskCounts.Max().Should().Be(maxConcurrency, because: $"there should be up to {maxConcurrency} tasks in flight.");
        }
Ejemplo n.º 4
0
        public async Task ShouldRunAllTasks()
        {
            //Arrange
            var logs = new List <Log>();
            Func <Log, Task> addLog = log =>
            {
                logs.Add(log);
                return(Task.FromResult(0));
            };

            var tasks = new List <Func <Task> >
            {
                async() => await addLog(new Log { Id = 1 }),
                async() => await addLog(new Log { Id = 2 }),
                async() => await addLog(new Log { Id = 3 }),
                async() => await addLog(new Log { Id = 4 }),
                async() => await addLog(new Log { Id = 5 })
            };

            //Act
            await ConcurrentTask.WhenAll(tasks, maxConcurrency : 5);

            //Assert
            logs.Should().BeEquivalentTo(new List <Log>
            {
                new Log {
                    Id = 1
                },
                new Log {
                    Id = 2
                },
                new Log {
                    Id = 3
                },
                new Log {
                    Id = 4
                },
                new Log {
                    Id = 5
                },
            });
        }
        public async Task ShouldReturnTasksInOrderDespiteWhenTheyResolve()
        {
            //Arrange
            var taskCompletions = Enumerable
                                  .Range(start: 1, count: 10)
                                  .Select(i => new TaskCompletionSource <int>())
                                  .ToList();
            Func <int, Task <int> > getResultFromTaskId = async taskId =>
            {
                await taskCompletions[taskId - 1].Task;
                return(taskId);
            };

            var tasks = Enumerable
                        .Range(start: 1, count: 10)
                        .Select(index => ((Func <Task <int> >)(async() => await getResultFromTaskId(index))));

            //Act
            int maxConcurrency = 3;
            var getResults     = ConcurrentTask.WhenAll(tasks, maxConcurrency);

            taskCompletions[4].SetResult(0);
            taskCompletions[1].SetResult(0);
            taskCompletions[0].SetResult(0);
            taskCompletions[9].SetResult(0);
            taskCompletions[2].SetResult(0);
            taskCompletions[6].SetResult(0);
            taskCompletions[8].SetResult(0);
            taskCompletions[3].SetResult(0);
            taskCompletions[7].SetResult(0);
            taskCompletions[5].SetResult(0);
            var results = await getResults;

            //Assert
            results.Should().BeEquivalentTo(new int[]
            {
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10
            }, ops => ops.WithStrictOrdering());
        }
Ejemplo n.º 6
0
        private static async Task <BitmapImage> GetOrPreCacheAsync(Uri uri, bool throwOnError, bool isPreCache)
        {
            ConcurrentTask task;
            string         key   = GetCacheFileName(uri);
            BitmapImage    image = null;

            lock (_concurrentTasks)
            {
                if (_concurrentTasks.ContainsKey(key))
                {
                    task = _concurrentTasks[key];
                }
                else
                {
                    task = new ConcurrentTask()
                    {
                        Task       = GetFromCacheOrDownloadAsync(uri, key, isPreCache),
                        IsPreCache = isPreCache
                    };
                    _concurrentTasks.Add(key, task);
                }
            }

            try
            {
                image = await task.Task;

                // if task was "PreCache task" and we needed "Get task" and task didnt return image we create new "Get task" and await on it.
                if (task.IsPreCache && !isPreCache && image == null)
                {
                    lock (_concurrentTasks)
                    {
                        task = new ConcurrentTask()
                        {
                            Task       = GetFromCacheOrDownloadAsync(uri, key, false),
                            IsPreCache = isPreCache
                        };
                        _concurrentTasks[key] = task;
                    }

                    image = await task.Task;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                if (throwOnError)
                {
                    throw ex;
                }
            }
            finally
            {
                lock (_concurrencyLock)
                {
                    if (_concurrentTasks.ContainsKey(key))
                    {
                        _concurrentTasks.Remove(key);
                    }
                }
            }

            return(image);
        }