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

lif*_*rop 5 c# object-pooling

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

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

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

2个问题:

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

  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}");
        }       
    }
}
Run Code Online (Sandbox Code Playgroud)

mjw*_*lls 6

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

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

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

不。他们会default(T)-即null。好像您正在考虑将其ArrayPool视为对象池。没错,但主要是一个数组池。它主要是在尝试避免分配和取消分配数组(而不是数组内部的对象)的开销。

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

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

返回到池中,您可以指示数据是否应该被清除与否。如果您不希望将数据存储在池中,建议将传递true为的值clearArray

clearArray布尔值

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

另外,您可以在调用之前自己清除缓冲区Return。我也建议阅读此链接

如果希望池包含对象(以避免new再次花费它们的开销),则可以这样做-但请确保将其设置clearArrayfalse(或保留为默认值)。