2011-06-15 30 views
6

.NET 4.0'da, özellikle olaylardan kaçınan, potansiyel olarak çok iş parçacıklı senaryolarda yeni bir eğilim fark ettim ve bunun yerine abone yöntemleri sağladım.Abone yöntemi vs olay

Örneğin, System.Threading.Tasks.Task ve Task<TResult> yerine Tamamlanmış veya bitirdi olayın ContinueWith() yöntemleri var. Başka bir örnek System.Threading.CancellationToken: bir CancellationRequested olayı yerine Register() yöntemine sahip.

o (olaylarla çok zarif olmaz) kolay bir iş zincirleme sağlar ve aynı zamanda (bu yolla, çünkü Task<TResult> uygun aşırı yüklenmeleri sağlayabilir Task<TResult>Task devralmak izin verdiğini çünkü Task.ContinueWith() mantıksal iken

, bir olay için mümkün olmazdı: bir EventHandler Görevinde bittiyse, yapabileceğiniz tek şey başka bir olayı yaratmaktır, diyelim ki Task<TResult> içinde bitmiş, çok güzel değil), ama bulamıyorum CancellationToken.Register() için aynı açıklama.

Peki, benzer senaryolardaki olayların dezavantajları nelerdir? Bu modeli de takip etmeli miyim? Açıklamak gerekirse, hangisini seçmeliyim? Birini diğerine ne zaman tercih etmeliyim?

public event EventHandler Finished; 

// or 

public IDisposable OnFinished(Action continuation) 

Çok teşekkür ederim!

+0

@Jon Skeet: Teşekkürler, melek parantezlerimin kaçmasına ihtiyacı olduğunu fark etmedim. – ShdNx

+0

UI olayları vb UI mesaj kuyruğu kullanılarak gönderilebilir ve bir temsilci veya basit bir Görev kullanarak karşılaştırıldığında potansiyel olarak gerçekten yavaş/ağır olabilir .. – CodingBarfield

+0

@Barfieldmv: Eylem Çağrısı Invoke/BeginInvoke ile aynı teknik kullanılarak yayınlanabilir UI iş parçacığı. Bu fark değil. –

cevap

2

Abone yöntemlerini kullanmanın bir avantajı, temsilci uygulamanızın gerçekleştirileceği iş parçacığını kolayca belirleyebilme yeteneğiniz olmasıdır. CancellationToken.Register() öğesinin this overload numaralı sayfasına bakın.

Upd: Aslında, aslında temsilci adresinize gönderilecek olan senkronizasyon bağlamını belirtebilirsiniz.

Eğilim hakkında haklısınız.

Yeni bileşenler olay tabanlı asenkron desen kullanmamalısınız: MSDN Magazine This article olarak şöyle demektedir. Visual Studio asenkron Topluluk teknoloji önizlemesi (CTP) bileşenleri Görevi dönmek ve Görev yerine SynchronizationContext yoluyla olayları yetiştirme hangi nesnelerin görev odaklı asenkron desen açıklayan belgesini içerir. Görev tabanlı API'ları, .NET'te eşzamanlı olmayan programlamanın geleceğidir.

ve makalenin gelir document

inisiyasyonu diyor ve TAP bir asenkron operasyonun tamamlanmasından bir tek işlem ile temsil edilen , ve nedenle adı tek bir yöntem yoktur. Bu BeginMethodName ve EndMethodName yöntemleri, ve MethodNameAsync ek olarak gerekli olan olay tabanlı asenkron desen veya DAP, aksine gerekli ıasyncresult desen veya APM desen, zıttır bir veya daha fazla olaya, olay eylemci delege türleri ve EventArg türetilmiş türleri.

Ve gerçekten de, pek çok yerine tek bir şeye dikkat etmek iyi bir şeydir. Ancak bu, DAP üzerinden abone yöntemlerinin avantajı değil, daha avantajlıdır.

+0

Bu mantıklı. Yöntemler (abone yöntemleri), olaylardan daha esnektir ve ayrıca daha az sorunludur (örneğin, olayla ilişkili bellek sızıntıları). Diğer taraftan, yöntemler geriye doğru bir adım gibi hissetmektedir, çünkü programcının geri aramaları depolayan bir listeyi uygulamak zorunda olduğu, geri arama listesinin iplik güvenliği konusunda endişelenmesi gerekmektedir. Öyleyse, genel olarak, olayların hala düz _subscriber_ yöntemleri üzerinde tercih edilmesi (burada EAP'den bahsetmemek) tercih edilir ve abone yöntemleri genellikle buna değmez (örneğin, özel geri arama davranışı belirtilirse hariç). Cevap için teşekkürler! – ShdNx

İlgili konular