Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

ความแตกต่างระหว่าง Foreach และ Parallel.Foreach ใน C#

ความแตกต่างหลัก

คุณสมบัติforeachParallel.ForEach
ThreadSingle ThreadMultiple Threads (Thread Pool)
ExecutionSequential (ลำดับ)Parallel (พร้อมกัน)
Performanceช้ากว่า (CPU-bound)เร็วกว่า (Multi-core)
NamespaceSystem (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 => { ... });