我有一个方法,它必须对大量数据进行迭代,并将处理后的结果返回给使用者线程进行序列化。流式PLinq适合最佳的性能。
因为这些操作很频繁,所以我使用对象池来缓存用于我的处理的容器,以最小化对象的创建。我尝试使用并发堆栈实现对象池(Concurrent袋和concurrentqueue显示了相同的问题)。在同样罕见的情况下,相同的项(查看哈希代码)是由同一个线程从池中获取的,尽管使用者线程没有释放它。我在池的获取和发布方法中添加了跟踪,这是输出:
下午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);
}
}
}我不知道如何防止这种情况发生。对于为什么会发生这种情况,以及如何防止这种情况,有什么想法吗?
发布于 2013-09-06 10:26:30
我看不出你贴的代码有什么问题。
在我看来,最有可能的情况是在同一个数组上调用PutObject()两次。但是如果没有看到更多的代码,就不可能知道。
https://stackoverflow.com/questions/18629647
复制相似问题