2016-10-17 32 views
6

C# Asynchronous foreach için bir yol var mı? id (ler) yerine Parallel.ForEachEşzamansız foreach

//This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 

Parallel.ForEach(clientIds, ProcessId); //runs the method in parallel 

static void ProcessId(int id) 
{ 
// just process the id 
} 

bir foreach şey olmalı kullanmak yerine, yöntemi ile uyumsuz olarak işlenmesi ama yönetmeye çalışıyorum

foreach(var id in clientIds) 
{ 
    ProcessId(id) //runs the method with each Id asynchronously?? 
} 

uyumsuz olarak çalışır edilecektir Program, Konsoldaki tüm kimlik (ler) i, Konsolu kapatmadan önce tamamlanmasını beklemelidir.

+0

gibi bitmiş olacaktır Görev dönmek zorunda kalacaktı. Çok iş parçacıklı foreach istediğini düşünüyorum ama 'Parallel.ForEach' (çok iş parçacıklı) kullanmak istemezsiniz? – Igor

+0

Peki, 2. Örnekte 'ProcessId' fonksiyonunuz asenkrobunoz mu? Bir Görev döndürüyor mu? Eğer asyncronously bunu yazmak veya –

+4

@Igor 'Parallel.ForEach' asenkron değil (Parallel.ForEach' yaptığı' gibi) Başka bir iş parçacığı üzerinde çalıştırmak zorunda Sadece "asenkron bir işlev yapmak" olamaz, zaman uyumlu paralel olarak görevleri işler . Ayrıca, uyumsuzluğu/beklemeyi desteklemez, bu yüzden ikisini karıştırmaya dikkat edin. –

cevap

12

Hayır, bu gerçekten mümkün değil.

Bunun yerine foreach döngüsünde Görev için Görev görevi olarak yapmak istediğiniz şeyi ekleyin ve sonra Task.WaitAll kullanın.

var tasks = new List<Task>(); 

foreach(var something in somethings) 
tasks.Add(DoJobAsync(something)); 

await Task.WhenAll(tasks); 

DoJobAsync yönteminin Görev döndürmesi gerektiğini unutmayın.

Güncelleme:

yönteminiz Görev ama başka bir şey (örneğin boşluk) aslında aynı olan iki seçenek var dönmezse:

1.Add Task.Run (aksiyon) görevler toplama

private Task DoJobAsync(Something something) 
{ 
    return Task.Run(() => DoJob(something)); 
} 
Görevi

dönen yöntemde yerine

tasks.Add(Task.Run(() => DoJob(something))); 

2.Wrap senkronizasyon yöntemi

Görev yürütme işleminden bazı sonuçlar almak istiyorsanız, Task<TResult> genel aracını kullanabilirsiniz.

+0

Bu, asenkron olarak çalışır mı? Bunu kodumda çoğaltmaya çalışıyorum, tüm DoJobAsync örnekleri birbiri ardına koşuyor gibi görünüyor. – Anzurio

6

Hedef yöntemi

static Task ProcessId(int id) 
{ 
    // just process the id 
} 

İşleme kimlikleri burada soruyorsun Değil emin ne bu

// This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 
// This gets all the tasks to be executed 
var tasks = clientIds.Select(id => ProcessId(id)). 
// this will create a task that will complete when all of the `Task` 
// objects in an enumerable collection have completed. 
await Task.WhenAll(tasks); 
+0

Daha hızlıydım: P –

+1

@PawelTroka ama Nkosi daha kolay kullanmıştı. .Select (id => ProcessId (is)) ': P –

+0

Evet, bu rep yarışında hala oldukça yeniyim. –