{"id":55937,"date":"2010-03-02T13:46:00","date_gmt":"2010-03-02T13:46:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2010\/03\/02\/faq-parallel-foreach-and-non-generic-collections\/"},"modified":"2010-03-02T13:46:00","modified_gmt":"2010-03-02T13:46:00","slug":"faq-parallel-foreach-and-non-generic-collections","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/faq-parallel-foreach-and-non-generic-collections\/","title":{"rendered":"FAQ :: Parallel.ForEach and non-generic collections?"},"content":{"rendered":"<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">.NET 2.0 introduced Generics to allow enhanced code reusability and type safety.&nbsp; Since then, generic collections (IEnumerable&lt;T&gt;, List&lt;T&gt;, Dictionary&lt;T&gt;, etc.) have become standard and are recommended over their non-generic counterparts (IEnumerable, ArrayList, HashTable, etc.).&nbsp; As a result, Parallel.ForEach only supports generic collections, so code like the following will fail to compile.<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span>IEnumerable<\/span><span> nonGenericCollection = &#8230;;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Parallel<\/span><span>.ForEach(nonGenericCollection, currentElement =&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>});<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\"><font size=\"3\">This issue applies to all non-generic collections (pretty much anything that was added before .NET 2.0), but here are some usual suspects that we&rsquo;ve seen folks run into: XmlNodeList, DataRowCollection, DataTableCollection.&nbsp; The error message is typically something like the following:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\"><font size=\"3\">&ldquo;The type arguments for method &lsquo;System.Threading.Tasks.Parallel.ForEach&lt;TSource&gt;) cannot be inferred from the usage. Try specifying the type arguments explicitly.&rdquo;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font size=\"3\">&middot;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\">&ldquo;The best overloaded method match for &#8216;System.Threading.Tasks.Parallel.ForEach&lt;object&gt;(System.Collections.Generic.IEnumerable&lt;object&gt;, System.Action&lt;object&gt;)&#8217; has some invalid arguments.&rdquo;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Fortunately, the workaround is simple.&nbsp; Since non-generic collections produce objects (IEnumerator.Current returns Object), it is always possible to produce an IEnumerable&lt;Object&gt; from an IEnumerable.&nbsp; For example:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span>static<\/span><span> <span>IEnumerable<\/span>&lt;<span>object<\/span>&gt; Cast(<span>IEnumerable<\/span> source)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; <span>foreach<\/span> (<span>object<\/span> o <span>in<\/span> source)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>yield<\/span> <span>return<\/span> o;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Even more fortunately, LINQ already provides this functionality:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>public<\/span><span> <span>static<\/span> <span>IEnumerable<\/span>&lt;TResult&gt; <\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; <\/span><span>Cast&lt;TResult&gt;(<span>this<\/span> <span>IEnumerable<\/span> source);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">So we can easily fix the initial example using this Cast extension method.<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><b><span>using<\/span><\/b><b><span> System.Linq;<\/p>\n<p><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">&hellip;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>Parallel<\/span><span>.ForEach(nonGenericCollection<b>.Cast&lt;<span>object<\/span>&gt;()<\/b>, <\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; c<\/span><span>urrentElement =&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>});<\/p>\n<p><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>.NET 2.0 introduced Generics to allow enhanced code reusability and type safety.&nbsp; Since then, generic collections (IEnumerable&lt;T&gt;, List&lt;T&gt;, Dictionary&lt;T&gt;, etc.) have become standard and are recommended over their non-generic counterparts (IEnumerable, ArrayList, HashTable, etc.).&nbsp; As a result, Parallel.ForEach only supports generic collections, so code like the following will fail to compile. &nbsp; IEnumerable nonGenericCollection = [&hellip;]<\/p>\n","protected":false},"author":485,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7908],"tags":[7907,7923,7909,7912],"class_list":["post-55937","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam","tag-net-4","tag-faq","tag-parallel-extensions","tag-task-parallel-library"],"acf":[],"blog_post_summary":"<p>.NET 2.0 introduced Generics to allow enhanced code reusability and type safety.&nbsp; Since then, generic collections (IEnumerable&lt;T&gt;, List&lt;T&gt;, Dictionary&lt;T&gt;, etc.) have become standard and are recommended over their non-generic counterparts (IEnumerable, ArrayList, HashTable, etc.).&nbsp; As a result, Parallel.ForEach only supports generic collections, so code like the following will fail to compile. &nbsp; IEnumerable nonGenericCollection = [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/55937","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\/485"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=55937"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/55937\/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=55937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=55937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=55937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}