【问题标题】:ArrayPool create method giving error in C#ArrayPool 创建方法在 C# 中给出错误
【发布时间】:2020-06-26 21:40:05
【问题描述】:

基本上,我想使用 ConcurrentAppend API 将数据从源文件并行读取到 Azure 数据湖中的目标文件。

另外,我不想一次全部从文件中读取数据,而是分块读取数据,我为此使用缓冲区。我想创建 5 个 1 MB 的缓冲区、5 个 2 MB 的缓冲区和 5 个 4 Mb 的缓冲区。每当源文件到达时,它将根据其大小使用适当的缓冲区,我将使用该缓冲区附加到目标。在每种情况/配置中,我不希望缓冲区超过 5 个。

我使用共享的 ArrayPool 来租用缓冲区。但是由于我有这个条件,即在每种情况下分配不应超过 5 个数组(1、2 和 4 MB)-> 我不得不使用一些条件来限制它。

我宁愿使用我可以创建的自定义池:

ArrayPool<byte> pool = ArrayPool<byte>.Create( One_mb , 5)

这将确保我的分配不超过 5 个数组,并且数组的最大大小为 1 MB。同样,我可以为 2 和 4 mb 的情况再创建两个缓冲池。这样我就不需要将这些条件限制为 5。

问题:

当我使用此自定义池时,我的目标文件中的数据已损坏。此外,目标文件大小增加了一倍,例如输入总和为 10 mb -> 目标文件显示 20 mb。

如果我使用相同的代码并从单个共享 ArrayPool 而不是这些自定义池中租用,我会得到正确的结果。

我做错了什么?

我的代码: https://github.com/ChahatKumar/ADLS/blob/master/CreatePool/Program.cs

【问题讨论】:

  • 不知道为什么这被否决了,这个问题似乎没问题
  • 我假设是因为代码在 github 中而不是在问题中。它可能与自定义池无关,而是它们读入字节数组并假设它已满的方式,这恰好在异地托管的代码中
  • 是的,我认为放置代码会使问题变得非常大..

标签: c# concurrency parallel-processing buffer pooling


【解决方案1】:

FileStream.Read 返回读取的字节数。这不一定是数组的大小,很可能会更小(如果没有读取字节,则为零)。您的 github 示例中的代码忽略了 Read 的值,并通过告诉下一个方法使用整个缓冲区来错误地假设缓冲区已被填充。因为您的数组非常大,所以您有可能(并且很可能)通过一次调用 Read 就不会完全读取它们(即使文件实际上那么大,FileStream 也有自己的内部缓冲区和缓冲区大小) .

您的方法应该如下所示。请注意,我将读取的实际字节数传递给ConcurrentAppend(我认为它符合长度参数):

int read;
while ((read = file.Read(buffer1, 0, buffer1.Length) > 0)
{
   c.ConcurrentAppend(filename, true, buffer1, 0, read);
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2018-02-16
    相关资源
    最近更新 更多