{"id":56056,"date":"2011-04-02T16:08:31","date_gmt":"2011-04-02T16:08:31","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2011\/04\/02\/little-known-gems-atomic-conditional-removals-from-concurrentdictionary\/"},"modified":"2011-04-02T16:08:31","modified_gmt":"2011-04-02T16:08:31","slug":"little-known-gems-atomic-conditional-removals-from-concurrentdictionary","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/little-known-gems-atomic-conditional-removals-from-concurrentdictionary\/","title":{"rendered":"Little-known gems: Atomic conditional removals from ConcurrentDictionary"},"content":{"rendered":"<p>ConcurrentDictionary&lt;TKey,TValue&gt;, first introduced in .NET 4, is an efficient dictionary data structure that enables thread-safe reading and writing, meaning that multiple threads may all be accessing the dictionary at the same time without corrupting it.&nbsp; It supports adding through its TryAdd method, conditional updates through its TryUpdate method, non-conditional adds or updates through its indexer&#8217;s setter, and removals through its TryRemove method, through which a key\/value pair is removed if the user-provided key matches.&nbsp; It also has several compound methods, such as GetOrAdd and AddOrUpdate.&nbsp; Lately, however, we&#8217;ve seen several folks ask for further support on ConcurrentDictionary, that of removing a key\/value pair only if <em>both<\/em> the user-provided key and value match the corresponding pair currently stored in the dictionary.&nbsp; <\/p>\n<p>You want it, you got it!&nbsp; I mean, literally, you already have it.&nbsp; As with Dictionary&lt;TKey,TValue&gt;, ConcurrentDictionary&lt;TKey,TValue&gt; implements ICollection&lt;KeyValuePair&lt;TKey,TValue&gt;&gt;. ICollection&lt;T&gt; exposes a Remove&lt;T&gt; method, so ICollection&lt;KeyValuePair&lt;TKey,TValue&gt;&gt; has a Remove(KeyValuePair&lt;TKey,TValue&gt;) method.&nbsp; Dictionary&lt;TKey,TValue&gt; implements Remove such that it only removes the element if both the key and the value match the data in the dictionary, and thus ConcurrentDictionary&lt;TKey,TValue&gt; does the same.&nbsp; And as it&#8217;s a concurrent data structure, ConcurrentDictionary&lt;TKey,TValue&gt; ensures that the comparison is done atomically with the removal.&nbsp; Tada!<\/p>\n<p>Of course, just as with Dictionary&lt;TKey,TValue&gt;, ConcurrentDictionary&lt;TKey,TValue&gt; implements ICollection&lt;KeyValuePair&lt;TKey,TValue&gt;&gt; explicitly, so if you want access to this method, you&#8217;ll need to first cast the dictionary to the interface.&nbsp; Here&#8217;s an extension&nbsp;method to help you with that cause:<\/p>\n<p style=\"padding-left: 30px\">public static bool TryRemove&lt;TKey, TValue&gt;(<br>&nbsp;&nbsp;&nbsp; this ConcurrentDictionary&lt;TKey, TValue&gt; dictionary, TKey key, TValue value)<br>{<br>&nbsp;&nbsp;&nbsp; if (dictionary == null) throw new ArgumentNullException(&#8220;dictionary&#8221;);<br>&nbsp;&nbsp;&nbsp; return ((ICollection&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;)dictionary).Remove(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new KeyValuePair&lt;TKey, TValue&gt;(key, value));<br>}<\/p>\n<p>Enjoy!<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ConcurrentDictionary&lt;TKey,TValue&gt;, first introduced in .NET 4, is an efficient dictionary data structure that enables thread-safe reading and writing, meaning that multiple threads may all be accessing the dictionary at the same time without corrupting it.&nbsp; It supports adding through its TryAdd method, conditional updates through its TryUpdate method, non-conditional adds or updates through its indexer&#8217;s [&hellip;]<\/p>\n","protected":false},"author":360,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7908],"tags":[7907,7916],"class_list":["post-56056","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam","tag-net-4","tag-coordination-data-structures"],"acf":[],"blog_post_summary":"<p>ConcurrentDictionary&lt;TKey,TValue&gt;, first introduced in .NET 4, is an efficient dictionary data structure that enables thread-safe reading and writing, meaning that multiple threads may all be accessing the dictionary at the same time without corrupting it.&nbsp; It supports adding through its TryAdd method, conditional updates through its TryUpdate method, non-conditional adds or updates through its indexer&#8217;s [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/56056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/360"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=56056"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/56056\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=56056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=56056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=56056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}