Saya ingin menangani koleksi secara paralel, tetapi saya kesulitan mengimplementasikannya dan oleh karena itu saya berharap bantuan.
Masalah muncul jika saya ingin memanggil metode bertanda async dalam C #, dalam lambda dari loop paralel. Sebagai contoh:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Masalah terjadi dengan jumlah menjadi 0, karena semua utas dibuat secara efektif hanya utas latar belakang dan Parallel.ForEach
panggilan tidak menunggu penyelesaian. Jika saya menghapus kata kunci async, metodenya terlihat seperti ini:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
// some pre stuff
var responseTask = await GetData(item);
responseTask.Wait();
var response = responseTask.Result;
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Ini bekerja, tetapi itu benar-benar menonaktifkan kepintaran menunggu dan saya harus melakukan beberapa penanganan pengecualian manual .. (Dihapus untuk singkatnya).
Bagaimana saya bisa menerapkan Parallel.ForEach
perulangan, yang menggunakan kata kunci tunggu dalam lambda? Apa itu mungkin?
Prototipe metode Parallel.ForEach mengambil Action<T>
parameter sebagai, tapi saya ingin menunggu lambda asinkron saya.
await
dariawait GetData(item)
dalam blok kode kedua Anda karena akan menghasilkan kesalahan kompilasi apa adanya.Jawaban:
Jika Anda hanya menginginkan paralelisme sederhana, Anda dapat melakukan ini:
Jika Anda membutuhkan sesuatu yang lebih kompleks, lihat posting Stephen Toub
ForEachAsync
.sumber
dop
tugas dan masing-masing dari mereka kemudian memproses beberapa bagian dari kumpulan input secara seri.Task.Run
tanpaawait
hasil, maka itu hanya melempar api-dan-lupa bekerja ke kolam utas. Itu hampir selalu merupakan kesalahan.Anda dapat menggunakan
ParallelForEachAsync
metode ekstensi dari Paket NuGet AsyncEnumerator :sumber
maxDegreeOfParallelism
>maxDegreeOfParalellism
Dengan
SemaphoreSlim
Anda dapat mencapai kontrol paralelisme.sumber
Implementasi ringan saya dari ParallelForEach async.
Fitur:
Contoh penggunaan:
sumber
Saya telah membuat metode ekstensi untuk ini yang memanfaatkan SemaphoreSlim dan juga memungkinkan untuk mengatur tingkat paralelisme maksimum
Penggunaan sampel:
sumber