EDIT Additional options and a slightly extended question below.
Consider this contrived and abstract example of a class body. It demonstrates four different w
The IL shows us that the for loop is the most efficient. There's no state machine to worry about.
for produces the following
IL_0036: br.s IL_0048
IL_0038: ldloc.0
IL_0039: ldloc.1
IL_003A: callvirt System.Collections.Generic.List<UserQuery+SomeClass>.get_Item
IL_003F: callvirt UserQuery+SomeClass.someAction
IL_0044: ldloc.1
IL_0045: ldc.i4.1
IL_0046: add
IL_0047: stloc.1
IL_0048: ldloc.1
IL_0049: ldloc.0
IL_004A: call System.Linq.Enumerable.Count
IL_004F: blt.s IL_0038
IL_0051: ret
The IL produced here for foreach shows the state machine at work. The LINQ version and the ForEach produce similar output.
IL_0035: callvirt System.Collections.Generic.List<UserQuery+SomeClass>.GetEnumerator
IL_003A: stloc.3
IL_003B: br.s IL_004B
IL_003D: ldloca.s 03
IL_003F: call System.Collections.Generic.List<UserQuery+SomeClass>.get_Current
IL_0044: stloc.1
IL_0045: ldloc.1
IL_0046: callvirt UserQuery+SomeClass.someAction
IL_004B: ldloca.s 03
IL_004D: call System.Collections.Generic.List<UserQuery+SomeClass>.MoveNext
IL_0052: brtrue.s IL_003D
IL_0054: leave.s IL_0064
IL_0056: ldloca.s 03
IL_0058: constrained. System.Collections.Generic.List<>.Enumerator
IL_005E: callvirt System.IDisposable.Dispose
IL_0063: endfinally
IL_0064: ret
I haven't done any tests but I think it's a safe assumption.
That being said, it doesn't mean for keyword should be used always. It all depends on your style, your teams style or if that piece of code your writing really needs every CPU cycle you can get your hands on.
I don't think I would compare AsParallel() with the for, foreach or the lambda equivalents. You'd split up CPU intensive tasks or blocking operations using AsParallel(), you wouldn't use it just iterating over a "normal" collection.