正确使用带有引用类型的ArrayPool <T>

时间:2019-08-05 23:29:14

标签: c# object-pooling

将ArrayPool与引用类型一起使用的正确方法是什么?

我以为它将充满使用默认构造函数“更新”的对象。

例如,在下面的代码中,当您第一次从ArrayPool中租用时,所有Foobars都为空。

2个问题:

  1. 由于从.Rent返回的对象最初都是空的,我是否需要先用初始化的对象填充数组池?

  2. 返回租用的对象时,我需要清除每个对象吗?例如foobar.Name = null; foobar.Place = null等...

public class Program
{
    public class Foobar {
        public string Name {get;set;}
        public string Place {get;set;}
        public int Index {get;set;}
    }

    public static void Main()
    {
        ArrayPool<Foobar> pool = ArrayPool<Foobar>.Shared;
        var foobars = pool.Rent(5);
        foreach(var foobar in foobars) {
            // prints "true"
            Console.WriteLine($"foobar is null? ans={foobar == null}");
        }       
    }
}

1 个答案:

答案 0 :(得分:6)

  

由于.Rent返回的对象最初都为空,因此我是否需要先用初始化的对象填充数组池?

您不需要 ,不需要。但是您可能至少应该对数组返回的任何内容进行null检查。

  

我以为它将充满使用默认构造函数“更新”的对象。

不。它们将是default(T)-即null。似乎您正在将ArrayPool视为对象池。是的,但主要是数组池主要是试图避免分配和取消分配数组(而不是数组内部的对象)的开销。

  

退还租用的物品时,我需要清除每个物品吗?

您不需要 ,不需要。这些不是您是否应该的通用答案,这取决于您的特定问题空间。

returning进入池时,您可以指示是否应该清除数据。如果您不希望将数据存储在池中,建议将true传递为clearArray的值。

  

clearArray布尔值

     

指示缓冲区的内容是否应   在重新使用之前将其清除。如果clearArray设置为true,以及池   将存储缓冲区以允许后续重用,Return(T [],   Boolean)方法将清除其内容数组,以便   使用Rent(Int32)方法的后续调用者将看不到   前一个呼叫者的内容。如果clearArray设置为false或   池将释放缓冲区,剩下的数组内容   保持不变。

或者,您可以在调用Return之前自己清除缓冲区。我也建议阅读this link

如果您想要包含对象的池(为避免再次new花费它们),可以这样做-但请确保设置{{ 1}}到clearArray(或将其保留为默认值)。