>我有一个方法,它必须迭代一大组数据,并将处理后的结果返回到使用者线程进行序列化。流式传输 PLinq 最适合性能方面。
由于这些操作很频繁,因此我使用对象池来缓存容器以供处理,以最大程度地减少对象创建。我尝试使用并发堆栈实现对象池(并发包和并发队列表现出相同的问题)。在同样极少数的情况下,同一线程从池中获取相同的项目(查看哈希代码),尽管它不是由使用者线程释放的。我在池的获取和释放方法中添加了跟踪,这是输出:
下午 5:11:32.250 获取线程 31
的项目16071020下午 5:11:32.254 获取线程 31
的项目16071020下午 5:11:32.260 将项目16071020放入线程 27
下午 5:11:32.286 将项目16071020放入线程 27
这是我正在使用的代码:
var itemsToProcess = data.AsParallel()
.Where(x => Filter(x))
.Select(row => Process(row));
在 Process 方法中,我将从池中获取对象:
result = ObjectPool.Instance.GetObject();
池类实现:
public class ObjectPool
{
private ConcurrentStack<object[]> _objects;
private int size;
private const int maxSize = 20000;
private static ObjectPool instance = new ObjectPool(500);
public static ObjectPool Instance
{
get { return instance; }
}
private ObjectPool(int size)
{
this.size = size;
_objects = new ConcurrentStack<object[]>();
}
public object[] GetObject()
{
object[] item;
if (_objects.TryPop(out item))
{
Trace.WriteLine(string.Format("Get item {0} for Thread {1}", item.GetHashCode(), Thread.CurrentThread.ManagedThreadId));
return item;
}
return new object[size];
}
public void Clear()
{
_objects.Clear();
}
public void PutObject(object[] item)
{
Trace.WriteLine(string.Format("Put item {0} for Thread {1}", item.GetHashCode(), Thread.CurrentThread.ManagedThreadId));
if (_objects.Count < maxSize)
{
_objects.Push(item);
}
}
}
我不知道如何防止这种情况的发生。关于为什么会发生这种情况以及如何防止它的任何想法?
我看不出您发布的代码有什么问题。
对我来说,最有可能的情况似乎是您在同一个数组上调用PutObject()
两次。但是,如果不看到更多的代码,就无法分辨。