Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Contoh berikut menunjukkan cara menulis metode ForEach yang menggunakan variabel partisi-lokal. Ketika perulangan ForEach dijalankan, ia membagi koleksi sumbernya menjadi beberapa partisi. Setiap partisi memiliki salinan variabel partisi-lokal sendiri. Variabel partisi-lokal mirip dengan variabel thread-local, kecuali bahwa beberapa partisi dapat berjalan pada satu utas.
Kode dan parameter dalam contoh ini sangat menyerupai metode For yang sesuai. Untuk informasi selengkapnya, lihat Cara: Menulis Perulangan Paralel.For dengan variabel Thread-Local.
Untuk menggunakan variabel partisi-lokal dalam perulangan ForEach, Anda harus memanggil salah satu metode kelebihan beban yang mengambil dua parameter jenis. Parameter jenis pertama, TSource, menentukan jenis elemen sumber, dan parameter jenis kedua, TLocal, menentukan jenis variabel partisi-lokal.
Contoh
Contoh berikut memanggil overload Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) untuk menghitung total dari array yang berisi satu juta elemen. Kelebihan beban ini memiliki empat parameter:
source, yang merupakan sumber data. Ini harus menerapkan IEnumerable<T>. Sumber data dalam contoh kami adalah objekIEnumerable<Int32>yang berisi satu juta anggota dan dikembalikan oleh metode Enumerable.Range.localInit, atau fungsi yang menginisialisasi variabel lokal partisi. Fungsi ini dipanggil sekali untuk setiap partisi tempat operasi Parallel.ForEach dijalankan. Contoh kami menginisialisasi variabel partisi-lokal menjadi nol.body, Func<T1,T2,T3,TResult> yang dijalankan oleh perulangan paralel pada setiap iterasi. Ciri khasnya adalahFunc\<TSource, ParallelLoopState, TLocal, TLocal>. Anda menyediakan kode untuk delegasi, dan perulangan melewati parameter input, yaitu:Elemen saat ini dari IEnumerable<T>.
Variabel ParallelLoopState yang dapat Anda gunakan dalam kode delegasi Anda untuk memeriksa keadaan perulangan.
Variabel partisi-lokal.
Delegasi Anda mengembalikan variabel partisi-lokal, yang kemudian diteruskan ke iterasi berikutnya dari loop yang dijalankan dalam partisi tersebut. Setiap partisi perulangan memiliki instance terpisah dari variabel ini.
Dalam contoh, delegasi menambahkan nilai setiap bilangan bulat ke variabel partisi-lokal, yang mempertahankan total nilai elemen bilangan bulat yang berjalan dalam partisi tersebut.
localFinally,Action<TLocal>mendelegasikan bahwa Parallel.ForEach memanggil ketika operasi perulangan di setiap partisi telah selesai. Metode Parallel.ForEach meneruskan nilai akhir variabel lokal-partisi untuk partisi perulangan ini melalui delegasiAction<TLocal>Anda, dan Anda menyusun kode yang melakukan tindakan yang diperlukan untuk menggabungkan hasil dari partisi ini dengan hasil dari partisi-partisi lainnya. Delegasi ini dapat dipanggil secara bersamaan oleh beberapa tugas. Karena itu, contoh menggunakan metode Interlocked.Add(Int32, Int32) untuk menyinkronkan akses ke variabeltotal. Jenis delegasi adalah Action<T>, sehingga tidak ada nilai pengembalian.
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;
// First type parameter is the type of the source elements
// Second type parameter is the type of the thread-local variable (partition subtotal)
Parallel.ForEach<int, long>(
nums, // source collection
() => 0, // method to initialize the local variable
(j, loop, subtotal) => // method invoked by the loop on each iteration
{
subtotal += j; //modify local variable
return subtotal; // value to be passed to next iteration
},
// Method to be executed when each partition has completed.
// finalResult is the final value of subtotal for a particular partition.
(finalResult) => Interlocked.Add(ref total, finalResult));
Console.WriteLine($"The total from Parallel.ForEach is {total:N0}");
}
}
// The example displays the following output:
// The total from Parallel.ForEach is 499,999,500,000
' How to: Write a Parallel.ForEach Loop That Has Thread-Local Variables
Imports System.Threading
Imports System.Threading.Tasks
Module ForEachThreadLocal
Sub Main()
Dim nums() As Integer = Enumerable.Range(0, 1000000).ToArray()
Dim total As Long = 0
' First type parameter is the type of the source elements
' Second type parameter is the type of the thread-local variable (partition subtotal)
Parallel.ForEach(Of Integer, Long)(nums, Function() 0,
Function(elem, loopState, subtotal)
subtotal += elem
Return subtotal
End Function,
Sub(finalResult)
Interlocked.Add(total, finalResult)
End Sub)
Console.WriteLine("The result of Parallel.ForEach is {0:N0}", total)
End Sub
End Module
' The example displays the following output:
' The result of Parallel.ForEach is 499,999,500,000