5

これは、私にとって、そして多くの .NET プログラマーにとって比較的一般的なタスクです
。.NET ThreadPool を使用して、特定の種類のタスクを処理する必要があるワーカー スレッドをスケジュールしたいと考えています。

復習として、ThreadPool とそれに関連付けられたデリゲートのキューイング メソッドのシグネチャは次のとおりです。

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)

これにより、ワーカークラスがタイプセーフになります(そして、より明確になります、IMHO):

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

私は何かが欠けているに違いない。

4

3 に答える 3

8

匿名のデリゲートまたはラムダをスレッドプールに (変数キャプチャを介して) 渡すことによって、好きな状態をパッケージ化するのは簡単なので、汎用バージョンは必要ありません。

たとえば、ユーティリティ関数を次のように記述できます。

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

ただし、プールされたタスクで状態が必要なときはいつでもデリゲートを自分で使用できるため、それほど便利ではありません。

于 2008-11-27T12:00:09.367 に答える
5

ワーク キューについて話しているようですね。(そして、私はクリッピーのように聞こえます...)

記録として、スレッドプールスレッドは通常、短い作業に使用する必要があります。理想的には、長寿命のキュー用に独自のスレッドを作成する必要があります。.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

于 2008-11-27T12:04:38.373 に答える
1

ThreadPool は、Generics を持たない .NET 1.1 から存在します。

彼らが後方互換性を壊さないように選択した方法が気に入っています:-)

于 2008-11-27T14:57:48.727 に答える