2008-11-27 78 views
5

對於我來說,這是一個相對常見的任務,我認爲,對於很多.NET程序員來說:我想使用.NET ThreadPool來調度需要處理給定類型的工作線程的ThreadPool任務。.NET中的通用線程池

先來回顧一下,對於線程池及其相關委託的排隊方法的簽名是:

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

因此,一個典型的通用工作線程類看起來是這樣的:

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 
    } 
} 

注意state參數的類型?這是Object

.NET團隊選擇不使QueueUserWorkItem方法(或整個ThreadPool類)具有通用性的原因是什麼?我不敢相信他們只是忽略了它。

這是我想怎麼看呢:

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

這將使工人階級類型安全(和很多更清晰,恕我直言):

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 
    } 
} 

我必須失去了一些東西。

回答

5

這聽起來像你在談論一個工作隊列? (我聽起來像clippy ...)

爲了記錄,線程池線程應該通常用於短小的工作。理想情況下,您應該爲長壽命隊列創建自己的線程。請注意,.NET 4.0可能會採用CCR/TPL庫,因此我們將免費獲得一些內置工作隊列 - 但編寫線程化工作隊列並不困難。你可以使它通用,太;-p

重的問題 - 我更喜歡捕捉變量的方法來穿過狀態成線(無論是ThreadThreadPool,或Control.Invoke):

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

這使您可以更細緻地控制線程,而不會使ThreadPool飽和。

+2

我不明白你不使用線程池的工作隊列的基本「執行」層的說法。使用*時,這是一個問題。NET ThreadPool類由於線程數量有限嗎?海事組織很自然地假設工作隊列中的任務很短。你能否詳細說明一下? – 2008-11-27 15:52:30

7

由於通過將匿名委託或lambda傳遞給線程池(通過變量捕獲)來封裝任何你喜歡的狀態是微不足道的,因此不需要通用版本。

例如,你可以寫一個效用函數:

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

但它不會是非常有用的,因爲你可以簡單地使用委託自己,你需要在合併的任務狀態的任何時間。

1

從.NET 1.1開始,ThreadPool不存在泛型。

我喜歡他們如何選擇不打破向後兼容性:-)

+5

我不認爲這是一個有效的論據。只要看看1.1中的所有容器類,它們在2.0中被「升級」爲使用泛型。另外,我並不是建議用它的通用副本替換Queue ...方法,而是在它旁邊添加通用版本。 – 2008-11-27 15:54:48