Example #1
0
        public DfTask <TResult> Run <TResult>(Func <Task <TResult> > function)
        {
            var task = new DfTask <TResult>();

            var currentListOfVisitedNodes = ListOfVisitedNodes.Current.Value ?? (ListOfVisitedNodes.Current.Value = new ListOfVisitedNodes());

            var firstVisit = !currentListOfVisitedNodes.VisitedNodes.Contains(nodeId);

            if (firstVisit)
            {
                currentListOfVisitedNodes.VisitedNodes.Add(nodeId);
            }

            Func <Task> runAction = async() =>
            {
                TResult result = default(TResult);

                Exception exception = null;

                try
                {
                    result = await function();
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                ListOfVisitedNodes.Current.Value = currentListOfVisitedNodes;

                DfTask.AsyncBlockingTask = null;

                if (exception == null)
                {
                    task.SetResult(result);
                }
                else
                {
                    task.SetException(exception);
                }

                if (DfTask.AsyncBlockingTask != null)
                {
                    await DfTask.AsyncBlockingTask;
                }
            };

            Func <Task> actionToAddToCollection =
                Utilities.MakeActionRunInCurrentExecutionContextIfAny(runAction);

            ListOfVisitedNodes.Current.Value = null;

            if (firstVisit)
            {
                DfTask.AsyncBlockingTask = collection.AddAsync(actionToAddToCollection);
            }
            else
            {
                DfTask.AsyncBlockingTask = collectionForReentrantItems.AddAsync(actionToAddToCollection);
            }

            return(task);
        }
Example #2
0
        public DfTask Run(Func <Task> action)
        {
            var task = new DfTask();

            var currentListOfVisitedNodes = ListOfVisitedNodes.Current.Value ?? (ListOfVisitedNodes.Current.Value = new ListOfVisitedNodes());

            var firstVisit = !currentListOfVisitedNodes.VisitedNodes.Contains(nodeId);

            if (firstVisit)
            {
                currentListOfVisitedNodes.VisitedNodes.Add(nodeId);
            }

            Func <Task> runAction = async() =>
            {
                Exception exception = null;

                try
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        exception = new OperationCanceledException(cancellationToken);
                    }
                    else
                    {
                        await action();
                    }
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                ListOfVisitedNodes.Current.Value = currentListOfVisitedNodes;

                DfTask.AsyncBlockingTask = null;

                if (exception == null)
                {
                    task.SetResult();
                }
                else
                {
                    task.SetException(exception);
                }

                if (DfTask.AsyncBlockingTask != null)
                {
                    await DfTask.AsyncBlockingTask;
                }
            };

            Func <Task> actionToAddToCollection =
                Utilities.MakeActionRunInCurrentExecutionContextIfAny(runAction);

            ListOfVisitedNodes.Current.Value = null;

            if (firstVisit)
            {
                DfTask.AsyncBlockingTask = collection.AddAsync(actionToAddToCollection);
            }
            else
            {
                DfTask.AsyncBlockingTask = collectionForReentrantItems.AddAsync(actionToAddToCollection);
            }

            return(task);
        }
        public static DfTask <T[]> WhenAll <T>(params DfTask <T>[] tasks)
        {
            DfTask <T[]> resultTask = new DfTask <T[]>();

            long totalCompleted = 0;

            long totalShouldComplete = tasks.Length;

            ConcurrentQueue <Exception> errors = new ConcurrentQueue <Exception>();

            ConcurrentQueue <(int index, T value)> results = new ConcurrentQueue <(int index, T value)>();

            TaskCompletionSource[] taskCompletionSources = new TaskCompletionSource[tasks.Length];

            for (var index = 0; index < tasks.Length; index++)
            {
                var task = tasks[index];

                taskCompletionSources[index] = new TaskCompletionSource();

                int index1 = index;

                task.OnCompleted(() =>
                {
                    try
                    {
                        results.Enqueue((index1, task.GetResult()));
                    }
                    catch (Exception e)
                    {
                        errors.Enqueue(e);
                    }

                    if (Interlocked.Increment(ref totalCompleted) != totalShouldComplete)
                    {
                        AsyncBlockingTask = taskCompletionSources[index1].Task;
                    }
                    else
                    {
                        AsyncBlockingTask = null;

                        if (errors.Count > 0)
                        {
                            resultTask.SetException(new AggregateException(errors.ToArray()));
                        }
                        else
                        {
                            resultTask.SetResult(results.OrderBy(x => x.index).Select(x => x.value).ToArray());
                        }

                        if (AsyncBlockingTask != null)
                        {
                            for (int i = 0; i < tasks.Length; i++)
                            {
                                int i1 = i;

                                if (i1 == index1)
                                {
                                    continue;
                                }

                                AsyncBlockingTask.ContinueWith(t =>
                                                               taskCompletionSources[i1].TryCompleteFromCompletedTask(t));
                            }
                        }
                        else
                        {
                            for (int i = 0; i < tasks.Length; i++)
                            {
                                if (i == index1)
                                {
                                    continue;
                                }

                                taskCompletionSources[i].SetResult();
                            }
                        }
                    }
                });
            }

            return(resultTask);
        }