Implementation of Parallel.ForEach for .NET 3.5
if (items == null)
        throw new ArgumentNullException("enumerable");



In the execution path where this exception is thrown, the reported argument name will not match the actual argument name. If this is the result of a rename refactoring (i.e. it's the parameter formerly known as "enumerable"), it's unfortunate, the string literal wasn't taken care of. That doesn't happen with ReShaper performing the refactoring, but if you're using the refactoring built into VS, I'm not sure it handles string literals; if you've manually "renamed" the argument, ...next time, use refactor/rename! ;)

Your implementation queues a work item for each item in items.


  ThreadPool.QueueUserWorkItem
  
  Queues a method for execution. The method executes when a thread pool thread becomes available.


The interesting bit is about its return value:


  Return Value
  
  Type: System.Boolean
  
  true if the method is successfully
  queued; NotSupportedException is thrown if the work item could not be
  queued.


There's the slight possibility that thread pooling might not be supported on the platform code is running on (from what I gathered of reasons for this exception to be thrown), in which case the first iteration will throw a NotSupportedException that the ForEach code might not be expecting at all... but letting it bubble up might just be the best thing to do in this case.



If I correctly understand what's going on, you're essentially spawning a thread to run an action, for each item in items. This might not be as efficient as you'd think it is: there's only so many concurrent operations that can happen on a quad-core processor, and then there's overhead too; sometimes it's more efficient to simply run the tasks sequentially.

And that's what Parallel.ForEach does:


  Parallel.ForEach
  
  Executes a foreach operation on an IEnumerable in which iterations may run in parallel.


Thus, I'd use your implementation with care, and perhaps use a profiler and benchmark against a "normal" foreach for a given number of iterations, but then your dev environment might have different computing power than your test and/or production environments, so careful with benchmarks, too.

It might be simpler to use the Microsoft NuGet package @JesseC.Slicer and @PhilBolduc mentioned in the comments...