PLinq 和对象池使用 ConcurrentCollections



>我有一个方法,它必须迭代一大组数据,并将处理后的结果返回到使用者线程进行序列化。流式传输 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()两次。但是,如果不看到更多的代码,就无法分辨。

相关内容

  • 没有找到相关文章

最新更新