Skip to content

Commit 3347544

Browse files
author
Lifeng Lu
committed
When a JTF is removed from a collection, it should ignore refCount.
It is called when a task is completed and all pending queue finished. Otherwise, the collection may reference a task which can be GCed.
1 parent 26830dc commit 3347544

File tree

2 files changed

+7
-5
lines changed

2 files changed

+7
-5
lines changed

src/Microsoft.VisualStudio.Threading/JoinableTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ internal void OnQueueCompleted()
995995

996996
foreach (IJoinableTaskDependent? collection in this.dependencyParents)
997997
{
998-
JoinableTaskDependencyGraph.RemoveDependency(collection, this);
998+
JoinableTaskDependencyGraph.RemoveDependency(collection, this, forceCleanup: true);
999999
}
10001000

10011001
if (this.mainThreadJobSyncContext is object)

src/Microsoft.VisualStudio.Threading/JoinableTaskDependencyGraph.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@ internal static JoinableTaskCollection.JoinRelease AddDependency(IJoinableTaskDe
7171
/// </summary>
7272
/// <param name="taskItem">The current joinableTask or collection.</param>
7373
/// <param name="child">The <see cref="IJoinableTaskDependent"/> to join as a child.</param>
74-
internal static void RemoveDependency(IJoinableTaskDependent taskItem, IJoinableTaskDependent child)
74+
/// <param name="forceCleanup">Ignore refCount, it is being used when the child task is completed.</param>
75+
internal static void RemoveDependency(IJoinableTaskDependent taskItem, IJoinableTaskDependent child, bool forceCleanup = false)
7576
{
7677
Requires.NotNull(taskItem, nameof(taskItem));
77-
JoinableTaskDependentData.RemoveDependency(taskItem, child);
78+
JoinableTaskDependentData.RemoveDependency(taskItem, child, forceCleanup);
7879
}
7980

8081
/// <summary>
@@ -400,7 +401,8 @@ internal static JoinableTaskCollection.JoinRelease AddDependency(IJoinableTaskDe
400401
/// </summary>
401402
/// <param name="parentTaskOrCollection">The current joinableTask or collection contains to remove a dependency.</param>
402403
/// <param name="joinChild">The <see cref="IJoinableTaskDependent"/> to join as a child.</param>
403-
internal static void RemoveDependency(IJoinableTaskDependent parentTaskOrCollection, IJoinableTaskDependent joinChild)
404+
/// <param name="forceCleanup">Ignore refCount, it is being used when the child task is completed.</param>
405+
internal static void RemoveDependency(IJoinableTaskDependent parentTaskOrCollection, IJoinableTaskDependent joinChild, bool forceCleanup)
404406
{
405407
Requires.NotNull(parentTaskOrCollection, nameof(parentTaskOrCollection));
406408
Requires.NotNull(joinChild, nameof(joinChild));
@@ -412,7 +414,7 @@ internal static void RemoveDependency(IJoinableTaskDependent parentTaskOrCollect
412414
{
413415
if (data.childDependentNodes is object && data.childDependentNodes.TryGetValue(joinChild, out int refCount))
414416
{
415-
if (refCount == 1)
417+
if (refCount == 1 || forceCleanup)
416418
{
417419
joinChild.OnRemovedFromDependency(parentTaskOrCollection);
418420

0 commit comments

Comments
 (0)