2009-12-03 30 views
8

yeni yan etki sadece görevi (yani: hayır sonuç döndürür bir görev) başlatmak için idomatic yol:TaskFactory.StartNew yöntemi neden genel değil?

Task Task.Factory.StartNew(Action<object>, object) 

Ama neden doesn' .NET 4.0 aşağıdaki API kullanarak TPL kullanarak Bu API imza t bu

Task Task.Factory.StartNew<T>(T, Action<T>) 

Teknik nedenlerden veya başka bir nedenle gibi bu

Task Task.Factory.StartNew<T>(Action<T>, T) 

ya benziyor?

cevap

7

Tamam, şimdi düzgün soru :)

Bunun bir direct replacement for ThreadPool.QueueUserWorkItem olması gerekiyordu çünkü inanmak anlıyorum. Ben biraz garip görünüyor katılıyorum ... ama yine de lambda ifadeleri kullanıyorsanız, bir durum parametresi (Action<object> yerine Action yerine) ve sadece değeri yakalamak için kullanmak daha kolay önceden ilgileniyorsun. Değeri ve işlevi ayrı ayrı belirtirseniz bu yardımcı olmaz :(

+1

Evet, ancak Görev , bir görevin sonuç türünde (TResult) jeneriktir, ancak "başlangıç ​​durumu" türünde genel değildir (yani: bir görevin girdisi). – Frank

+0

Öyleyse ... Task.Factory.StartNew çağrıldığında, otomatik olarak threadpool'dan bir iş parçacığı alır mı? –

+0

@Padu: Evet, inanıyorum - farklı bir iş parçacığı kullanan kendi görev fabrikanıza sahip olmanıza rağmen, inanıyorum. –

3

Stephen Toub (MSFT) tarafından yapılan bir yayına göre, devlet verilerini geçmek için kapatmaya güveneceğimizi varsayıyorlar. aynı zamanda imza belirsizliği ile ilgili bir bahane de vardı (http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/1988294c-de41-476a-a104-aa550b7409f5)

Ancak, bu sorunu çözmek için kapaklara güvenmek, daha iyi bir çözüm bekleyen geçici bir hacke benziyor gibi gözüküyor, ama işe yarar, ama uzun vadeli bir çözüm değil. Çoğu kez bir temsilci yöntemini eylem olarak tanımlamanın en basit yaklaşım olacağı, ancak bu, global varsayı kullanmamız gerektiği veya durum parametresi geçişinden hariç tutulduğumuz anlamına gelir.

I Hugo'nun önerilerinden biri gibi (MS forum mesajından). Hugo, TaskState türünü tanıtmayı önerdi, bu da jenerik belirsizlik sorununu aşmanın akıllıca bir yolu gibi görünüyor. - Bir Değer etrafında sadece basit bir sarıcı

public Task<T>(Action<T> function, TaskState<T> state); 
    public Task<T,TResult>(Func<T,TResult> function, TaskState<T> state); 

ActionState null sınıfı gibi bir çok olacaktır:

Task.Factory.StartNew() imza ve Görev() gibi kurucusuna bu uygulama üyesi.

var myTask = new Task(MyMethod, new TaskState(stateInfo)); 
    ... 

    public void MyMethod(StateInfo stateInfo) { ... } 

TaskState <> çözüm mükemmel değildir, ama bu tip döküm kapatılması güvenmek yerine çok daha iyi bir çözüm gibi görünüyor: Uygulamada, kullanarak TaskState aşağıdaki gibi görünebilir.

+0

+1 İlginç, teşekkürler. – Frank

+2

Komik, TPL ekibi 4.5'deki iyileştirmelerle ilgili bir [white paper] (http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235962.aspx) yayınladı. “en iyi uygulamalar” bölümünde (s. 11), kapanışta değişkenleri yakalamak yerine durumun en iyi şekilde (Eylem aşırı yükü üzerinden) geçilmesinin en iyi olduğunu açıklarlar.Şimdi, bu öneriyle ilgili olarak, genel bir aşırı yük kesinlikle arzu edilebilir. – Frank

İlgili konular