Nad rámec async/ pro I/O poskytuje .NET pro — spouštění výpočtů na více jádrech. Klíčový rozdíl: / je pro souběžnost I/O (neblokující čekání), zatímco , a PLINQ jsou pro paralelizaci CPU-intenzivní práce.
Nad rámec async/ pro I/O poskytuje .NET pro — spouštění výpočtů na více jádrech. Klíčový rozdíl: / je pro souběžnost I/O (neblokující čekání), zatímco , a PLINQ jsou pro paralelizaci CPU-intenzivní práce.
awaitasyncawaitTask.RunParallelasync/await → I/O-bound concurrency. Frees the thread during waits (DB, network).
Does NOT add CPU parallelism.
Parallelism → CPU-bound work spread across MULTIPLE CORES (computation, processing).
Use Task.Run, Parallel.For/ForEach, PLINQ.
// run a CPU-intensive computation on a thread pool thread (don't block the caller)
int result = await Task.Run(() => ExpensiveComputation());
// run multiple in parallel and combine
var tasks = items.Select(item => Task.Run(() => Process(item)));
var results = await Task.WhenAll(tasks); // wait for all
Task.Run plánuje práci do vlákna z fondu vláken — používejte ji k paralelizaci výpočtu vázaného na CPU (NE pro I/O, kde async/await již postačuje bez dodatečných vláken).
// Parallel.For/ForEach — process a collection across cores
Parallel.ForEach(items, item => Process(item)); // automatically uses multiple cores
Parallel.For(0, 1000, i => Compute(i));
// PLINQ — parallel LINQ
var results = data.AsParallel().Where(x => IsValid(x)).Select(Transform).ToList();
Parallel.For/ForEach a PLINQ (.AsParallel()) automaticky distribuují práci na jádra — skvělé pro CPU-těžké zpracování nezávislých položek. (Vyplatí se to jen pro skutečně CPU-vázanou práci s větším objemem — existuje režie.)
// parallel code accessing SHARED state needs synchronization or thread-safe types
lock (_lock) { _counter++; } // lock for mutual exclusion
Interlocked.Increment(ref _counter); // lock-free atomic
var dict = new ConcurrentDictionary<string, int>(); // thread-safe collection
Porozumění Tasks a paralelismu nad rámec async/await je důležité znalosti na úrovni seniora pro vytváření výkonných aplikací v C#, a klíčový rozdíl mezi souběžností I/O a paralelismem CPU je klíčovou myšlenkou — běžný zdroj zmatení. async/await zpracovává souběžnost vázanou na I/O (uvolňování vláken během čekání), ale nepřidává paralelismus CPU, zatímco práce vázaná na CPU (výpočty, zpracování dat) prospívá skutečnému paralelismu na jádrech prostřednictvím Task.Run (přesunutí CPU práce do vláken z fondu), Parallel.For/ForEach a PLINQ (.AsParallel()).
Znalost, který nástroj se hodí — async/await pro I/O, nástroje TPL paralelismu pro práci vázanou na CPU — je nezbytná pro efektivní optimalizaci výkonu, protože použití nesprávného nástroje (např. očekávání, že async zrychlí výpočet, nebo spouštění vláken pro I/O, které async efektivně zpracovává) je neúčinné.
Rovněž důležité je pochopit bezpečnost vláken: paralelní kód přistupující ke sdílenému stavu potřebuje synchronizaci (lock, Interlocked pro atomické operace nebo bezpečné kolekce jako ConcurrentDictionary) aby se zabránilo podmínkám Race — kritické otázce správnosti v paralelním kódu.
Porozumění rozdílu I/O-versus-CPU, nástrojům paralelismu (Task.Run, Parallel, PLINQ) a požadavkům na bezpečnost vláken je cenné pro psaní správného a výkonného souběžného a paralelního C#.
Protože moderní aplikace často potřebují jak souběžnost I/O tak paralelismus CPU, a protože výběr správného přístupu a správné zpracování bezpečnosti vláken jsou to, co činí paralelní kód efektivním a správným, jedná se o důležité, často relevantní znalosti seniora pro výkonově citlivý vývoj v C#.