Utover / for I/O, tilbyr .NET for — kjøring av beregninger på tvers av flere kjerner. Hovedforskjellen: / er for I/O-konkurrens (ikke-blokkerende venting), mens , , og PLINQ er for parallelisering av CPU-intensivt arbeid.
Utover / for I/O, tilbyr .NET for — kjøring av beregninger på tvers av flere kjerner. Hovedforskjellen: / er for I/O-konkurrens (ikke-blokkerende venting), mens , , og PLINQ er for parallelisering av CPU-intensivt arbeid.
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 planlegger arbeid på en tråd pool tråd — bruk det til å parallelisere CPU-bound beregning (IKKE for I/O, hvor async/await allerede er tilstrekkelig uten ekstra tråder).
// 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 og PLINQ (.AsParallel()) distribuerer arbeid automatisk over kjerner — utmerket for CPU-tung prosessering av uavhengige elementer. (Bare verdt det for genuint CPU-bound, omfattende arbeid — det er 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
Å forstå Tasks og parallelisme utover async/await er viktig kunnskap på seniorinivå for å bygge ytelsesorienterte C#-applikasjoner, og den avgjørende distinksjonen mellom I/O-konkurrens og CPU-parallelisme er den sentrale innsikten — et vanlig forvirringsmoment. async/await håndterer I/O-bound konkurrens (frigjøring av tråder under venting) men legger ikke til CPU-parallelisme, mens CPU-bound arbeid (beregninger, databehandling) drar nytte av faktisk parallelisme på tvers av kjerner via Task.Run (avlasting av CPU-arbeid til tråd pool tråder), Parallel.For/ForEach, og PLINQ (.AsParallel()).
Å vite hvilket verktøy som passer — async/await for I/O, TPL-parallelismeverktøyene for CPU-bound arbeid — er essensielt for effektiv ytelseoptimalisering, siden bruk av feil verktøy (f.eks. forvente at async akselererer beregning, eller å starte tråder for I/O som async håndterer effektivt) er ineffektivt.
Like viktig er å forstå trådssikkerhet: parallell kode som får tilgang til delt tilstand trenger synkronisering (lock, Interlocked for atomiske operasjoner, eller trådsikre samlingskolleksjoner som ConcurrentDictionary) for å unngå race conditions — et kritisk korreksjonsproblem i parallell kode.
Å forstå I/O-vs-CPU-distinksjonen, parallelismeverktøyene (Task.Run, Parallel, PLINQ), og trådsikkerhetskrav er verdifullt for å skrive korrekt, ytelsesorientert samtidig og parallell C#.
Siden moderne applikasjoner ofte trenger både I/O-konkurrens og CPU-parallelisme, og siden valg av rett tilnærming og korrekt håndtering av trådssikkerhet er det som gjør parallell kode effektiv og korrekt, er dette viktig, hyppig relevant seniorkunnskaps for ytelseskritisk C#-utvikling.