2011-07-21 26 views
5

Arka planda yürütmek istediğim birkaç eylem var, ancak birbiri ardına senkronize olarak yürütülmesi gerekiyor.Task.ContinueWith kullanarak bir yürütme kuyruğu oluşturma?

Bunu başarmak için Task.ContinueWith yöntemini kullanmak iyi bir fikir olup olmadığını merak ediyordum. Bununla ilgili herhangi bir sorun var mı? (Karşılık gelen görev zaten tamamlandıysa TPL derhal devamı planlamak gerçeğini kullanarak) tasarlandığı gibi bu çalışması gerekir

private object syncRoot =new object(); 
private Task latestTask; 

public void EnqueueAction(System.Action action) 
{ 
    lock (syncRoot) 
    { 
     if (latestTask == null) 
      latestTask = Task.Factory.StartNew(action); 
     else 
      latestTask = latestTask.ContinueWith(tsk => action()); 
    } 
} 

cevap

5

:

Benim kod şöyle görünür.

Şahsen bu durumda görevler çizmek için eşzamanlı bir kuyruk (ConcurrentQueue) kullanarak özel bir iş parçacığı kullanacağım - bu daha açık ancak kodun okunmasını ayrıştırmak daha kolay, özellikle de ne kadar görev bulmak istediğinizde Şu anda kuyruğa alınmışlar vb.

+0

ConcurrentQueue etrafında BlockingCollection kullanmak bir iyileştirme olacaktır. Daha sonra, bir engelleme koleksiyonu üzerinde sadece bir foreach kullanan bir Görev/İşçi ipi gönderilebilir. Yeni bir öğe sıraya ekleninceye veya forma engelleyen koleksiyonda CompleteAdding() çağrılana kadar foreach "askıda kalacak". –

7

Son zamanlarda kendimi keşfettiğim bir kusur var, çünkü bu görevlerin sırayla yürütülmesini sağlama yöntemini de kullanıyorum.

Uygulamamda bu mini kuyruklardan binlerce örnek vardı ve hızlı bir şekilde bellek sorunları yaşadığımı keşfettim. Bu kuyruklar genellikle boşta kaldığı için, son tamamlanan görev nesnesine uzun süre tuttum ve çöp toplanmasını önledim. Son tamamlanan görevin sonuç nesnesi genellikle 85.000 bayttan fazla olduğu için Büyük Nesne Yığına (çöp toplama sırasında sıkıştırma yapmaz) tahsis edildi. Bu, LOH'nin parçalanmasına ve boyutta sürekli olarak büyüyen sürecin sonuçlanmasıyla sonuçlandı.

Bundan kaçınmak için, no-op görevini kilitinizdeki gerçek numaradan sonra planlayabilirsiniz. Gerçek bir çözüm için, zamanlamayı kontrol etmenin farklı bir yöntemine geçmem gerekecek.

0

Bu pasajı kullandım ve tasarlandığı şekilde çalışmasını sağladım. Benim durumumdaki örneklerin sayısı binlerce, ancak tek haneli olarak çalışmıyor. Yine de, şimdiye kadar sorun yok.

Herhangi bir sorun varsa ConcurrentQueue örneğiyle ilgilenir miydim?

Teşekkürler

+0

Süper basit bir sıra için bu benim için hala iyi çalışıyor. Ama daha fazla ilgili görev kuyrukları kullanmaya başladım [Dataflow] (http://msdn.microsoft.com/en-us/library/hh228603 (v = vs.110) .aspx) daha kullanmaya başladım. – lukebuehler