Selain / untuk I/O, .NET menyediakan untuk — menjalankan komputasi di beberapa core. Perbedaan kunci: / adalah untuk konkurensi I/O (penundaan non-blocking), sementara , , dan PLINQ adalah untuk paralelisasi pekerjaan intensif CPU.
Selain / untuk I/O, .NET menyediakan untuk — menjalankan komputasi di beberapa core. Perbedaan kunci: / adalah untuk konkurensi I/O (penundaan non-blocking), sementara , , dan PLINQ adalah untuk paralelisasi pekerjaan intensif 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 menjadwalkan pekerjaan pada thread thread pool — gunakan untuk paralelisasi komputasi terikat CPU (BUKAN untuk I/O, di mana async/await sudah cukup tanpa thread ekstra).
// 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 dan PLINQ (.AsParallel()) secara otomatis mendistribusikan pekerjaan ke seluruh core — sempurna untuk pemrosesan CPU-heavy dari item independen. (Hanya bermanfaat untuk pekerjaan yang benar-benar terikat CPU dan berukuran besar — ada 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
Memahami Task dan paralelisme di luar async/await adalah pengetahuan tingkat senior yang penting untuk membangun aplikasi C# yang performan, dan perbedaan krusial antara konkurensi I/O dan paralelisme CPU adalah wawasan kunci — titik kebingungan yang umum. async/await menangani konkurensi terikat I/O (membebaskan thread selama penundaan) tetapi tidak menambah paralelisme CPU, sementara pekerjaan terikat CPU (komputasi, pemrosesan data) mendapat manfaat dari paralelisme aktual di seluruh core melalui Task.Run (menjalankan pekerjaan CPU ke thread pool), Parallel.For/ForEach, dan PLINQ (.AsParallel()).
Mengetahui alat mana yang cocok — async/await untuk I/O, alat paralelisme TPL untuk pekerjaan terikat CPU — sangat penting untuk optimasi performa yang efektif, karena menggunakan yang salah (misalnya mengharapkan async untuk mempercepat komputasi, atau meluncurkan thread untuk I/O yang async tangani secara efisien) tidak efektif.
Sama pentingnya adalah memahami keamanan thread: kode paralel mengakses status bersama memerlukan sinkronisasi (lock, Interlocked untuk operasi atomik, atau koleksi thread-safe seperti ConcurrentDictionary) untuk menghindari kondisi race — kekhawatiran korektness kritis dalam kode paralel.
Memahami perbedaan I/O-vs-CPU, alat paralelisme (Task.Run, Parallel, PLINQ), dan persyaratan keamanan thread bernilai untuk menulis concurrent dan parallel C# yang benar dan performan.
Karena aplikasi modern sering membutuhkan baik konkurensi I/O maupun paralelisme CPU, dan karena memilih pendekatan yang tepat dan menangani keamanan thread dengan benar adalah apa yang membuat kode paralel efektif dan benar, ini adalah pengetahuan senior yang penting dan sering relevan untuk pengembangan C# sensitif performa.