Përtej / për I/O, .NET ofron për — ekzekutimi i kompjutimeve në shumë bërthama. Dallimi kyç: / është për konkurencën e I/O (pritjet jo-bllokuese), ndërsa , , dhe PLINQ janë për paralelizimin e punës intensive të CPU.
Përtej / për I/O, .NET ofron për — ekzekutimi i kompjutimeve në shumë bërthama. Dallimi kyç: / është për konkurencën e I/O (pritjet jo-bllokuese), ndërsa , , dhe PLINQ janë për paralelizimin e punës intensive të CPU.
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 planifikon punën në një thread të thread pool — përdore atë për të paralelizuar komputimin e kushtëzuar nga CPU (JO për I/O, ku async/await tashmë përsëritemi mjaftueshëm pa thread-e shtesë).
// 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 dhe PLINQ (.AsParallel()) automatikisht shpërndajnë punën në bërthama — e shkëlqyer për përpunimin e rëndë të CPU të artikujve të pavarur. (Vlen vetëm për punën e vërtetë të kushtëzuar nga CPU dhe të konsiderueshme — ka regjistrim.).
// 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
Komprehensioni i Tasks dhe paralelizmit përtej async/await është njohuri e rëndësishme e nivelit të lartë për ndërtimin e aplikacioneve të performuara në C#, dhe dallimi thelbësor midis konkurencës së I/O dhe paralelizmit të CPU është përfundimi kyç — një pikë e zakonshme konfuzioni. async/await menaxhon konkurencën e kushtëzuar nga I/O (duke liruar thread-et gjatë pritjeve) por nuk shton paralelizmin e CPU, ndërsa puna e kushtëzuar nga CPU (llogaritjet, përpunimi i të dhënave) përfiton nga paralelizmi i vërtetë përgjatë bërthamave përmes Task.Run (zhvendosja e punës së CPU në thread-et e thread pool), Parallel.For/ForEach, dhe PLINQ (.AsParallel()).
Janë esenciale të dish se cili mjet përshtatet — async/await për I/O, mjeteve të paralelizmit TPL për punën e kushtëzuar nga CPU — për optimizimin efektiv të performancës, pasi përdorimi i atij të gabuar (p.sh. pritshmëria se async përshpejton komputimin, ose hapja e thread-eve për I/O që async menaxhon në mënyrë efikase) është jo-efektiv.
Njësoj e rëndësishme është kuptimi i sigurimit të thread-it: kodi paralel që hyrjet në gjendje të ndarë nevojitet sinkronizim (lock, Interlocked për operacione atomike, ose koleksione të sigurta për thread si ConcurrentDictionary) për të evituar gara — një shqetësim thelbësor korrektsie në kod paralel.
Komprehensimi i dallit I/O-vs-CPU, mjeteve të paralelizmit (Task.Run, Parallel, PLINQ), dhe kërkesave të sigurimit të thread-it është i vlefshëm për shkrimin e kodit të saktë, të performuar konkurent dhe paralel në C#.
Duke qenë se aplikacionet moderne shpesh kanë nevojë për konkurencën e I/O dhe paralelizmin e CPU, dhe duke qenë se zgjedhja e qasjes së duhur dhe trajtimi i sigurimit të thread-it në mënyrë korrekte janë ajo që bënë kodin paralel efektiv dhe të saktë, kjo është njohuri e rëndësishme, shpesh e përfshirë për zhvillimin e C# të ndjeshëm ndaj performancës në nivel të lartë.