private static JoinableTask? AddDependingSynchronousTask()

in src/Microsoft.VisualStudio.Threading/JoinableTaskDependencyGraph.cs [807:881]


            private static JoinableTask? AddDependingSynchronousTask(IJoinableTaskDependent taskOrCollection, JoinableTask synchronousTask, ref int totalEventsPending)
            {
                Requires.NotNull(taskOrCollection, nameof(taskOrCollection));
                Requires.NotNull(synchronousTask, nameof(synchronousTask));
                Assumes.True(Monitor.IsEntered(taskOrCollection.JoinableTaskContext.SyncContextLock));

                JoinableTask? thisJoinableTask = taskOrCollection as JoinableTask;
                if (thisJoinableTask is object)
                {
                    if (thisJoinableTask.IsCompleteRequested)
                    {
                        if (!thisJoinableTask.IsFullyCompleted)
                        {
                            // A completed task might still have pending items in the queue.
                            int pendingCount = thisJoinableTask.GetPendingEventCountForSynchronousTask(synchronousTask);
                            if (pendingCount > 0)
                            {
                                totalEventsPending += pendingCount;
                                return thisJoinableTask;
                            }
                        }

                        return null;
                    }
                }

                ref JoinableTaskDependentData data = ref taskOrCollection.GetJoinableTaskDependentData();
                DependentSynchronousTask? existingTaskTracking = data.dependingSynchronousTaskTracking;
                while (existingTaskTracking is object)
                {
                    if (existingTaskTracking.SynchronousTask == synchronousTask)
                    {
                        existingTaskTracking.ReferenceCount++;
                        return null;
                    }

                    existingTaskTracking = existingTaskTracking.Next;
                }

                JoinableTask? eventTriggeringTask = null;

                if (thisJoinableTask is object)
                {
                    int pendingItemCount = thisJoinableTask.GetPendingEventCountForSynchronousTask(synchronousTask);
                    if (pendingItemCount > 0)
                    {
                        totalEventsPending += pendingItemCount;
                        eventTriggeringTask = thisJoinableTask;
                    }
                }

                // For a new synchronous task, we need apply it to our child tasks.
                var newTaskTracking = new DependentSynchronousTask(synchronousTask)
                {
                    Next = data.dependingSynchronousTaskTracking,
                };

                Thread.MemoryBarrier();

                data.dependingSynchronousTaskTracking = newTaskTracking;

                if (data.childDependentNodes is object)
                {
                    foreach (KeyValuePair<IJoinableTaskDependent, int> item in data.childDependentNodes)
                    {
                        JoinableTask? childTiggeringTask = AddDependingSynchronousTask(item.Key, synchronousTask, ref totalEventsPending);
                        if (eventTriggeringTask is null)
                        {
                            eventTriggeringTask = childTiggeringTask;
                        }
                    }
                }

                return eventTriggeringTask;
            }