假设我在一个并行处理循环中处理了1000个项目。
处理项目有时需要使用带有专用算法的Calculation
对象,该算法必须是单线程的,并且创建起来有些昂贵。
我当时正在考虑创建一个带有List<Calculation>
的容器类,可以要求它在空闲时提供一个这样的对象,否则将创建一个新的Calculation
对象。
容器类内部的管理必须手动进行编码,并且必须针对不同线程中的错误进行证明,因此我认为可能会容易忽略一些故障。
您是否知道此方案的C#模式或类型?
答案 0 :(得分:2)
这称为对象池。如果创建或销毁对象的成本很高并且有重用的机会,则很有用。
您可以手动操作池。必要时取物品,用后退回。这很容易出现错误。您可以忘记返回项目(将项目留给GC可能会占用诸如文件句柄之类的资源)。您还可以提早返回,这将导致池的两个使用者同时对同一个对象进行操作。
您还可以使用object resurrection确定何时删除某项并将其自动拉入池中。我认为这在实践中不起作用。根据GC的行为,这可能导致资源消耗的巨大波动。还有很多潜在的非常严重的错误的可能性。
很可能您只需要正确使用对象池即可。像
var obj = pool.Take();
try {
Use(obj);
}
finally {
pool.Return(obj);
}
浮现在脑海。您也可以为此使用using
。
答案 1 :(得分:1)
我已经通过使用ConcurrentBag集合而不是列表成功实现了这种线程池。这是线程安全的。像这样:
ConcurrentBag<Calculation> active = new ConcurrentBag<Calculation>();
Calculation calc;
if ( idle.IsEmpty || !idle.TryTake(calc)) {
calc = new Calculation();
}
/* start the Calculation object */
/* when it completes toss it in the bag for reuse ... */
idle.Add (calc);
一个包就像一个列表,但无序。这对您想做的事很好。