ความแตกต่างหลัก
| คุณสมบัติ | foreach | Parallel.ForEach |
| Thread | Single Thread | Multiple Threads (Thread Pool) |
| Execution | Sequential (ลำดับ) | Parallel (พร้อมกัน) |
| Performance | ช้ากว่า (CPU-bound) | เร็วกว่า (Multi-core) |
| Namespace | System (Built-in) | System.Threading.Tasks |
| Order | สม่ำเสมอ | ไม่รับประกันลำดับ |
| Exception Handling | ง่าย | ซับซ้อน (AggregateException) |
ตัวอย่างเปรียบเทียบ Performance
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace DemoApplication
{
class Demo
{
static void Main(string[] args)
{
var animals = new List<string>
{ "cat", "rat", "deer", "elephant", "lion", "tiger", "dog", "pig",
"buffalo", "rabbit", "horse", "cheetah", "cow", "goat", "sheep",
"donkey", "zebra", "wolf", "fox", "leopard", "monkey", "kangaroo",
"giraffe", "hippo" };
// Normal foreach
var sw1 = Stopwatch.StartNew();
foreach (string animal in animals)
{
SimulateWork(animal);
}
Console.WriteLine($"foreach: {sw1.Elapsed.TotalMilliseconds:F2} ms");
// Parallel.ForEach
var sw2 = Stopwatch.StartNew();
Parallel.ForEach(animals, animal =>
{
SimulateWork(animal);
});
Console.WriteLine($"Parallel.ForEach: {sw2.Elapsed.TotalMilliseconds:F2} ms");
Console.ReadLine();
}
static void SimulateWork(string name)
{
Thread.Sleep(10); // จำลองงานหนัก
Console.WriteLine($"{name} - Thread: {Thread.CurrentThread.ManagedThreadId}");
}
}
}
Output ตัวอย่าง
foreach: 240.50 ms
cat - Thread: 1
rat - Thread: 1
...
Parallel.ForEach: 45.20 ms
cat - Thread: 1
dog - Thread: 3
lion - Thread: 4
... (ลำดับสุ่ม, Thread IDs หลายตัว)
เมื่อไหร่ควรใช้ Parallel.ForEach?
- ✅ CPU-Bound Work: คำนวณหนัก, Image Processing, Math
- ✅ Independent Items: แต่ละ Item ไม่พึ่งพากัน
- ✅ Collection ใหญ่พอให้คุ้มค่า Overhead
เมื่อไหร่ ไม่ควร ใช้?
- ❌ I/O-Bound: ใช้
await / Task.WhenAll ดีกว่า
- ❌ Collection เล็ก (Overhead มากกว่าประโยชน์)
- ❌ ต้องการลำดับ (Order) เฉพาะเจาะจง
- ❌ Shared State / Race Condition
- ❌ Thread-Unsafe Code (non-thread-safe collections)
ตัวเลือกควบคุม Parallelism
var options = new ParallelOptions
{
MaxDegreeOfParallelism = 4, // จำกัด Thread สูงสุด 4
CancellationToken = cts.Token
};
Parallel.ForEach(items, options, item => { ... });