@@ -317,20 +317,23 @@ public bool TryRemove(KeyValuePair<K, V> item)
317317 {
318318 if ( this . dictionary . TryGetValue ( item . Key , out var node ) )
319319 {
320- if ( EqualityComparer < V > . Default . Equals ( node . Value , item . Value ) )
321- {
322- var kvp = new KeyValuePair < K , N > ( item . Key , node ) ;
320+ lock ( node )
321+ {
322+ if ( EqualityComparer < V > . Default . Equals ( node . Value , item . Value ) )
323+ {
324+ var kvp = new KeyValuePair < K , N > ( item . Key , node ) ;
323325
324326#if NET6_0_OR_GREATER
325- if ( this . dictionary . TryRemove ( kvp ) )
327+ if ( this . dictionary . TryRemove ( kvp ) )
326328#else
327- // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/
328- if ( ( ( ICollection < KeyValuePair < K , N > > ) this . dictionary ) . Remove ( kvp ) )
329+ // https://devblogs.microsoft.com/pfxteam/little-known-gems-atomic-conditional-removals-from-concurrentdictionary/
330+ if ( ( ( ICollection < KeyValuePair < K , N > > ) this . dictionary ) . Remove ( kvp ) )
329331#endif
330- {
331- node . WasRemoved = true ;
332- AfterWrite ( node ) ;
333- return true ;
332+ {
333+ node . WasRemoved = true ;
334+ AfterWrite ( node ) ;
335+ return true ;
336+ }
334337 }
335338 }
336339 }
@@ -361,14 +364,20 @@ public bool TryUpdate(K key, V value)
361364 {
362365 if ( this . dictionary . TryGetValue ( key , out var node ) )
363366 {
364- node . Value = value ;
367+ lock ( node )
368+ {
369+ if ( ! node . WasRemoved )
370+ {
371+ node . Value = value ;
365372
366- // It's ok for this to be lossy, since the node is already tracked
367- // and we will just lose ordering/hit count, but not orphan the node.
368- this . writeBuffer . TryAdd ( node ) ;
369- TryScheduleDrain ( ) ;
370- this . policy . OnWrite ( node ) ;
371- return true ;
373+ // It's ok for this to be lossy, since the node is already tracked
374+ // and we will just lose ordering/hit count, but not orphan the node.
375+ this . writeBuffer . TryAdd ( node ) ;
376+ TryScheduleDrain ( ) ;
377+ this . policy . OnWrite ( node ) ;
378+ return true ;
379+ }
380+ }
372381 }
373382
374383 return false ;
0 commit comments