Bortom / för I/O tillhandahåller .NET för — körning av beräkningar över flera kärnor. Nyckelskillnaden: / är för I/O-concurrency (icke-blockerande väntningar), medan , och PLINQ är för parallelisering av CPU-intensivt arbete.
Bortom / för I/O tillhandahåller .NET för — körning av beräkningar över flera kärnor. Nyckelskillnaden: / är för I/O-concurrency (icke-blockerande väntningar), medan , och PLINQ är för parallelisering av CPU-intensivt arbete.
asyncawaitasyncawaitTask.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 schemalägger arbete på en trådpoolstråd — använd det för att parallelisera CPU-bunden beräkning (INTE för I/O, där async/await redan är tillräckligt utan extra trådar).
// 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 och PLINQ (.AsParallel()) distribuerar automatiskt arbete över kärnor — utmärkt för CPU-tung bearbetning av oberoende objekt. (Är bara värt det för genuint CPU-bundet, omfattande arbete — det finns overhead.)
// 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
Att förstå Tasks och parallellism bortom async/await är viktig kunskaper på senior-nivå för att bygga högpresterande C#-applikationer, och den avgörande skillnaden mellan I/O-concurrency och CPU-parallellism är nyckelinsikten — en vanlig förvirrningspunkt. async/await hanterar I/O-bunden concurrency (frigör trådar under väntningar) men lägger INTE till CPU-parallellism, medan CPU-bundet arbete (beräkningar, databearbetning) gynnas av faktisk parallellism över kärnor via Task.Run (flytta CPU-arbete till trådpoolstrådar), Parallel.For/ForEach och PLINQ (.AsParallel()).
Att veta vilket verktyg som passar — async/await för I/O, TPL-parallellismverktygen för CPU-bundet arbete — är väsentligt för effektiv prestandaoptimering, eftersom att använda fel verktyg (t.ex. förvänta att async snabbar upp beräkningar, eller starta trådar för I/O som async hanterar effektivt) är ineffektivt.
Lika viktigt är att förstå trådsäkerhet: parallell kod som får åtkomst till delad status behöver synkronisering (lock, Interlocked för atomära operationer, eller trådsakra samlingar som ConcurrentDictionary) för att undvika race conditions — en kritisk korrektnessfråga i parallell kod.
Att förstå I/O-vs-CPU-skillnaden, parallellismverktygen (Task.Run, Parallel, PLINQ) och trådäkerhetskraven är värdefullt för att skriva korrekt, högpresterande concurrent och parallel C#.
Eftersom moderna applikationer ofta behöver både I/O-concurrency och CPU-parallellism, och eftersom att välja rätt approach och hantera trådäkerhet korrekt är det som gör parallell kod effektiv och korrekt, är detta viktig, ofta relevant senior-kunskap för prestandakänslig C#-utveckling.