private async Task ExecuteTask(RuntimeTask task)
        {
            await Task.WhenAll(task.Dependencies);

            var sem = _semaphores.GetOrAdd(task.Name, new SemaphoreSlim(task.MaxDegreeOfParallelism));
            await sem.WaitAsync();

            task.Task.Start();
            await task.Task;

            sem.Release();
        }
        private List <RuntimeTask> CreateRuntimeTaskForNode(TaskConfigTreeNode node, List <RuntimeTask> parentTasks)
        {
            var result = new List <RuntimeTask>();

            foreach (var taskConfigConnection in node.TaskConfig.Connections)
            {
                var task = new Task(() =>
                {
                    Console.WriteLine($"{DateTime.Now}: Executing task {node.TaskConfig.Name} and connection {taskConfigConnection}.");
                    Thread.Sleep(1000);
                });
                var runtimeTask = new RuntimeTask(task, taskConfigConnection, node.TaskConfig.Name, node.TaskConfig.MaxDegreeOfParallelism);
                if (parentTasks != null)
                {
                    if (node.TaskConfig.OnlyIfDependentTaskSucceeded)
                    {
                        runtimeTask.Dependencies.AddRange(parentTasks.Select(rt => rt.Task));
                    }
                    else
                    {
                        var parentRuntimeTaskWithSameConnection = parentTasks.SingleOrDefault(rt => rt.Connection == taskConfigConnection);
                        if (parentRuntimeTaskWithSameConnection != null)
                        {
                            runtimeTask.Dependencies.Add(parentRuntimeTaskWithSameConnection.Task);
                        }
                        else
                        {
                            //TBD
                        }
                    }
                }

                result.Add(runtimeTask);
            }

            return(result);
        }