@@ -16,7 +16,7 @@ internal sealed class HierarchyIdMap
1616 /// </summary>
1717 public uint Add ( HierarchyNode node )
1818 {
19- VisualStudio . Shell . ThreadHelper . ThrowIfNotOnUIThread ( ) ;
19+ Debug . Assert ( VisualStudio . Shell . ThreadHelper . CheckAccess ( ) ) ;
2020
2121#if DEBUG
2222 foreach ( var reference in this . nodes . Values )
@@ -35,7 +35,9 @@ public uint Add(HierarchyNode node)
3535 {
3636 idx = this . nodes . Count ;
3737 }
38- this . nodes [ idx ] = new WeakReference < HierarchyNode > ( node ) ;
38+
39+ var addSuccess = this . nodes . TryAdd ( idx , new WeakReference < HierarchyNode > ( node ) ) ;
40+ Debug . Assert ( addSuccess , "Failed to add a new item" ) ;
3941
4042 return ( uint ) idx + 1 ;
4143 }
@@ -45,22 +47,18 @@ public uint Add(HierarchyNode node)
4547 /// </summary>
4648 public void Remove ( HierarchyNode node )
4749 {
48- VisualStudio . Shell . ThreadHelper . ThrowIfNotOnUIThread ( ) ;
50+ Debug . Assert ( VisualStudio . Shell . ThreadHelper . CheckAccess ( ) ) ;
4951
5052 Debug . Assert ( node != null , "Called with null node" ) ;
5153
5254 var idx = ( int ) node . ID - 1 ;
5355
54- var removeCheck = this . nodes . TryGetValue ( idx , out var weakRef ) ;
56+ var removeCheck = this . nodes . TryRemove ( idx , out var weakRef ) ;
5557
5658 Debug . Assert ( removeCheck , "How did we get an id, which we haven't seen before" ) ;
5759 Debug . Assert ( weakRef != null , "Double delete is not expected." ) ;
60+ Debug . Assert ( weakRef . TryGetTarget ( out var found ) && object . ReferenceEquals ( node , found ) , "The node has the wrong id, or was GC-ed before." ) ;
5861
59- var checkReference = weakRef . TryGetTarget ( out var found ) && object . ReferenceEquals ( node , found ) ;
60-
61- Debug . Assert ( checkReference , "The node has the wrong id." ) ;
62-
63- this . nodes [ idx ] = null ;
6462 this . freedIds . Push ( idx ) ;
6563 }
6664
@@ -71,18 +69,19 @@ public HierarchyNode this[uint itemId]
7169 {
7270 get
7371 {
74- VisualStudio . Shell . ThreadHelper . ThrowIfNotOnUIThread ( ) ;
72+ Debug . Assert ( VisualStudio . Shell . ThreadHelper . CheckAccess ( ) ) ;
7573
76- var i = ( int ) itemId - 1 ;
77- if ( 0 <= i && i < this . nodes . Count )
74+ var idx = ( int ) itemId - 1 ;
75+ if ( 0 <= idx && idx < this . nodes . Count )
7876 {
79- var reference = this . nodes [ i ] ;
80- if ( reference != null && reference . TryGetTarget ( out var node ) )
77+ if ( this . nodes . TryGetValue ( idx , out var reference ) && reference != null && reference . TryGetTarget ( out var node ) )
8178 {
8279 Debug . Assert ( node != null ) ;
8380 return node ;
8481 }
8582 }
83+
84+ // This is a valid return value, this gets called by VS after we deleted the item
8685 return null ;
8786 }
8887 }
0 commit comments