gpt4 book ai didi

c# - HAA0502 显式新引用类型分配

转载 作者:行者123 更新时间:2023-12-03 21:00:35 27 4
gpt4 key购买 nike

我有 ASP.Net Core 2.1 , C#应用。我正在使用 Clr 堆分配分析器

https://marketplace.visualstudio.com/items?itemName=MukulSabharwal.ClrHeapAllocationAnalyzer

其中一种方法如下所示

例#1

public void ConfigureServices(IServiceCollection services) {

services.AddSingleton<IPocoDynamo>(serviceProvider => {
var pocoDynamo = new PocoDynamo(serviceProvider.GetRequieredService<IAmazonDynamoDB>());
pocoDynamo.SomeMethod();
return pocoDynamo;
});

}

示例#2
public async Task<EventTO> AddEvent(EventTO eventObj)
{
try
{
throw new Exception("Error!");
}
catch (Exception ex)
{
Logger.Log(ex, eventObj);
return null;
}
}

我在整个应用程序中使用 DI。但无论分析仪在哪里发现 new关键字的东西,它是警告

HAA0502 Explicit new reference type allocation



此外,无论在何处使用 Lambda 表达式,都会发出警告(例如在 ex#1 中)
Warning HAA0301 Heap allocation of closure Captures:

是什么导致了这个以及如何解决这个问题?

谢谢!

最佳答案

堆分配分析器 用于标记您的代码执行的所有分配。这不是您希望一直使用的:考虑以下愚蠢的代码

        public static string MyToString(object? o)
{
if (o == null)
throw new ArgumentNullException(nameof(o)); // HAA0502 here

return o.ToString() ?? string.Empty;
}
分析器会以警告的形式发出 HAA0502 作为标记行上的信息,告诉您正在分配一个新实例。现在,在这种情况下您在做什么很明显,这是一个微不足道的警告,但分析器的目的是帮助您发现可能使您的代码变得更慢的讨厌的分配。
现在考虑这个愚蠢的代码:
        public static void Test1()
{
for (int i = 0; i < 100; i++)
{
var a = i + 1;

var action = new Action(
() => // HAA0301 Heap allocation of closure Capture: a
{
Console.WriteLine(a);
}
);

action();
}
}
除了 HAA0502 将被标记在 new Action( 上因为我们正在创建一个新对象,所以 lambda 上有一个额外的警告: HAA0301 .这就是分析器变得更有用的原因:这里分析器告诉您运行时将创建一个包含您捕获的变量 a 的新对象。 .如果您不熟悉这一点,您可能会认为该代码被转换成这样的东西(仅用于解释目的):
        private sealed class Temp1
{
public int Value1 { get; }

public Temp1(int value1)
{
Value1 = value1;
}

public void Method1()
{
Console.WriteLine(Value1);
}
}

public static void Test1()
{
for (int i = 0; i < 100; i++)
{
var a = i + 1;

var t = new Temp1(a);
t.Method1();
}
}
在后面的代码中,很明显每次迭代都在分配一个对象。
您可能遇到的主要问题是: 分配对象有问题吗? 在 99.9% 的情况下,这不是问题,您可能会接受编写可读、精确和简洁的代码的简单性,而无需处理低级细节, 但是 如果您遇到性能问题(即剩余的 0.01%),分析器会变得非常方便,因为它会在您 的一个镜头中显示或代表您的编译器 正在分配一些东西。分配对象需要一个 future 的垃圾收集器周期来回收内存。
关于您的代码,您正在使用工厂模式通过 DI 初始化服务:该代码运行一次。因此,您正在分配一个新对象也就不足为奇了。因此,您可以安全地抑制这部分代码的警告。您可以使用 IDE 来生成抑制代码。这就是为什么我建议禁用分析器并仅在寻找性能问题时启用它。

关于c# - HAA0502 显式新引用类型分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58138603/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com