何よりもまず、私は@briantylerに同意する:ThreadLocal<T>
または静的フィールドのスレッドが何をしたいと考えられます。それを出発点にして、それがあなたのニーズを満たしていない場合は、他の選択肢も検討してください。
複雑で柔軟代替は、シングルトンオブジェクトプールです。その最も単純な形式では、あなたのプールの種類は次のようになります。あなたがプールとして、プリミティブクラスまたは構造体(すなわちObjectPool<MyComponent>
)の観点タイプT
を考えている場合
は
public sealed class ObjectPool<T>
{
private readonly ConcurrentQueue<T> __objects = new ConcurrentQueue<T>();
private readonly Func<T> __factory;
public ObjectPool(Func<T> factory)
{
__factory = factory;
}
public T Get()
{
T obj;
return __objects.TryDequeue(out obj) ? obj : __factory();
}
public void Return(T obj)
{
__objects.Enqueue(obj);
}
}
これはとても便利いないようです建てられた任意のスレッドのコントロールを持っていません。しかし、あなたはLazy<T>
やTask<T>
モナドのためのあなたのタイプT
を代用し、正確に何をしたい得ることができます。
プールの初期化:
Func<Task<MyComponent>> factory =() => Task.Run(() => new MyComponent());
ObjectPool<Task<MyComponent>> pool = new ObjectPool<Task<MyComponent>>(factory);
// "Pre-warm up" the pool with 16 concurrent tasks.
// This starts the tasks on the thread pool and
// returns immediately without blocking.
for (int i = 0; i < 16; i++) {
pool.Return(pool.Get());
}
使用法:
// Get a pooled task or create a new one. The task may
// have already completed, in which case Result will
// be available immediately. If the task is still
// in flight, accessing its Result will block.
Task<MyComponent> task = pool.Get();
try
{
MyComponent component = task.Result; // Alternatively you can "await task"
// Do something with component.
}
finally
{
pool.Return(task);
}
この方法はThreadLocal
またはスレッドの静的フィールドであなたのコンポーネントを維持するよりも複雑ですが、制限のような派手な何かをする必要がある場合プールされたインスタンスの数、プールの抽象化は非常に便利です。
public sealed class ObjectPool<T>
{
private readonly Queue<T> __objects;
public ObjectPool(IEnumerable<T> items)
{
__objects = new Queue<T>(items);
}
public T Get()
{
lock (__objects)
{
while (__objects.Count == 0) {
Monitor.Wait(__objects);
}
return __objects.Dequeue();
}
}
public void Return(T obj)
{
lock (__objects)
{
__objects.Enqueue(obj);
Monitor.Pulse(__objects);
}
}
}
は、コンポーネントについての詳細を知る必要があります。プールが排水された後
EDIT
Basicは
Get
どのブロックとプールの実装「Xインスタンスのセットを固定しました」。 1)それはCOMコンポーネントですか? 2)どのようにWCFサービスをホストしていますか? IIS? Windowsサービスの中に?コンソールアプリですか? 3)WCFサービスのインスタンスコントロールとは何ですか?シングルトン?コールごとに?セッションごとに? – MickyD@MickyDによると、コンポーネントの新しいインスタンスを作成するための呼び出しをスレッドしても、スレッドの安全性の問題は解決されません(実際には悪化すると思います)。 – AWinkle
本当に必要なのは、スレッドプールではなくオブジェクトプールです。 –