.NET

2008-11-27 19 views
5
'da bulunan Genel ThreadPool

Burada benim için göreceli olarak yaygın bir görev var ve bence, bir .NET programcısı için:
Belirli bir tür işlemek için gereken çalışan iş parçacıklarını zamanlamak için .NET ThreadPool'u kullanmak istiyorum. görevler..NET

tazelemek gerekirse

, ThreadPool'da ve ilişkili temsilci kuyruk yöntemi için imzalar şunlardır:

public class Worker<T> { 
    public void schedule(T i_task) { 
     ThreadPool.QueueUserWorkItem(execute, i_task) 
    } 
    private void execute(Object o){ 
     T task = (T)o; //What happened to the type safety? 
     executeTask(task); 
    } 
    private void executeTask(T i_task){ 
     //process i_task 
    } 
} 

:

public static bool QueueUserWorkItem (
    WaitCallback callBack, 
    Object state 
) 
public delegate void WaitCallback (Object state) 

nedenle, tipik bir jenerik çalışan iş parçacığı sınıfı benzer görünümde olacaktır state parametresinin türüne dikkat edin? Object!

.NET ekibinin neden QueueUserWorkItem yöntemini (veya tüm ThreadPool sınıfını) jenerik yapmamayı seçmesinin nedeni nedir? Sadece gözden kaçırdıklarına inanamıyorum.

//in the ThreadPool class: 
public static bool QueueUserWorkItem<T> (
    WaitCallback<T> callBack, 
    T state 
) 
public delegate void WaitCallback<T> (T state) 

Bu tür güvenli işçi sınıfı (ve çok daha net, IMHO) yapmak istiyorum:

public class Worker<T> { 
    public void schedule(T i_task) { 
     ThreadPool.QueueUserWorkItem<T>(execute, i_task) 
    } 
    private void execute(T i_task){ 
     //process i_task 
    } 
} 

ben eksik gerekir Burada

bunu görmek istiyorum nasıl şey.

cevap

5

Bir iş kuyruğundan bahsediyormuşsunuz gibi mi geliyor? (ve ben de kulağa hoş geliyor ...)

Kayıt için, iş parçacığı iş parçacıkları genellikle kısa iş parçaları için kullanılmalıdır. Uzun ömürlü bir sıra için ideal olarak kendi iş parçanızı oluşturmalısınız. .NET 4.0, CCR/TPL kitaplıklarını benimsiyor olabileceğine dikkat edin; bu nedenle, bazı dahili iş kuyruğu ücretsiz olarak alacağız - ancak iş parçacığı bir iş kuyruğu yazmak zor değil.

Thread t = new Thread(() => SomeMethod(arg)); 
    t.IsBackground = true; 
    t.Name = "Worker n"; 
    t.Start(); 

Bu veriyor: Ben parçacığı içine durumunu geçen yakalanan değişkenler yaklaşımı tercih (onlar Thread, ThreadPool veya Control.Invoke) - Ve

soru Re o jenerik çok ;-p yapabilir ThreadPool'u doyurmadan iş parçacığı üzerinde çok daha ayrıntılı denetim.

+2

:-) geriye uyumluluk kırmamaya seçti nasıl gibi. * * Kullanırken bu bir problemdir.NET ThreadPool sınıfı nedeniyle sınırlı sayıda iplik var mı? IMO, bir iş kuyruğundaki görevlerin kısa olduğunu varsaymak doğaldır. Lütfen detaylandırır mısın? –

7

Anonim bir temsilci veya lambda iş parçacığına (değişken yakalama yoluyla) geçirerek istediğiniz herhangi bir durumu paketlemek önemsiz olduğundan, genel bir sürüm gerekmez.

Örneğin, bir yardımcı fonksiyon yazabiliriz:

static void QueueItem<T>(Action<T> action, T state) 
{ 
    ThreadPool.QueueUserWorkItem(delegate { action(state); }); 
} 

Ama sadece bir temsilci kendiniz toplanmış görev devlete ihtiyacımız her zaman kullanabilirsiniz gibi, pek de kullanışlı olmaz.

1

ThreadPool, .NET 1.1'den beri Generics'e sahip değil.

onlar bir çalışma sıranın 'yürütme' altında yatan katman olarak bir iş parçacığı havuzu kullanmayan senin argüman anlamıyorum

+5

Bunun geçerli bir argüman olduğunu düşünmüyorum. Sadece, 2.0'da generikleri kullanmaya "yükseltilmiş" olan tüm konteyner sınıflarına bakın. Artı Ben * sırayla * sıraya koymak yerine * genel bir karşılığı ile, ama genel sürümü eklemek için önermek değildi. –