通过


MemoryStream 最大容量更新和异常行为已更改

MemoryStream 类现在强制实施最大字节容量 0x7FFFFFC7 ,这是 CLR 支持的字节数组的实际最大长度。 此外,尝试设置 MemoryStream超出此最大值的容量或长度时,异常行为已更改。 MemoryStream现在会因为无效的容量或长度值引发ArgumentOutOfRangeException,而不是引发OutOfMemoryException

已引入的版本

.NET 11 预览版 1

以前的行为

以前,MemoryStream 允许的容量高达 int.MaxValue0x7FFFFFFF),这可能会在尝试分配超出 CLR 支持的内存限制 0x7FFFFFC7 时导致 OutOfMemoryException

当将MemoryStream的容量或长度设置为超过支持限制的值时,会抛出一个OutOfMemoryException

var stream = new MemoryStream();
stream.SetLength(int.MaxValue); // Threw OutOfMemoryException.

新行为

从 .NET 11 开始,MemoryStream 施加最大字节容量限制 0x7FFFFFC7 。 尝试将容量或长度设置为超出此限制的值时,会引发一个 ArgumentOutOfRangeException

无效容量或长度值的异常类型已从OutOfMemoryExceptionArgumentOutOfRangeException更改为 。

var stream = new MemoryStream();
stream.SetLength(int.MaxValue); // Throws ArgumentOutOfRangeException.

破坏性变更的类型

此更改为行为更改

更改原因

引入了此更改,使行为与 CLR 的实际内存分配限制保持一致 MemoryStream。 上述行为允许开发人员指定超出支持限制的容量或长度,从而导致运行时失败,并出现描述性较低的异常(OutOfMemoryException)。 通过封顶最大容量和抛出 ArgumentOutOfRangeException,该更改可提高运行时的可靠性,并向开发人员提供更清晰的反馈。

检查任何用于设置MemoryStream容量或长度的代码,以确保它不超过支持的最大容量。

如果代码在处理容量或长度操作时捕获OutOfMemoryExceptionMemoryStream,则应将其更新为捕获ArgumentOutOfRangeException,因为这两种异常依然有可能发生:

  • ArgumentOutOfRangeException 在尝试设置无效的容量或长度(超过最大值)时将被引发。
  • OutOfMemoryException 如果计算机上内存不足,仍可能会引发。
var stream = new MemoryStream();
try
{
    stream.SetLength(someLength);
}
catch (ArgumentOutOfRangeException)
{
    // Handle invalid capacity/length scenario.
}
catch (OutOfMemoryException)
{
    // Handle out of memory scenario.
}

还可以在设置容量或长度之前添加检查,以避免异常:

bool TrySetLength(MemoryStream stream, long length)
{
    if (length > Array.MaxLength)
    {
        return false;
    }
    
    stream.SetLength(length);
    return true;
}

受影响的 API