2 回答
TA贡献1884条经验 获得超4个赞
期望您进行如下设计:
public async Task<IEnumerable<Ticket>> GetTicket(int id)
{
return await _memoryCache.GetOrCreateAsync(_cachingFunctionalty.BuildCachingName(id), entry =>
{
var localId = id;
entry.SlidingExpiration = TimeSpan.FromSeconds(10);
return GetTicket_uncached(localId);
});
}
现在您没有可以在闭包范围之外修改的变量,Re-sharper会发出警告,只要理论上有可能在正在执行的闭包之外修改变量,从而导致不可预测的结果。同样适用于其他方法。在实际操作中,您应该对所有其他对象遵循相同的操作,可以在闭包范围之外对其进行修改,从而创建本地版本
TA贡献1796条经验 获得超4个赞
此消息来自“堆分配查看器”插件。创建lambda并传递Func
给时GetOrCreateAsync
,您要从调用方法(GetTicket
)中捕获一些值,并在以后使用它们。
编译此代码时,编译器会将此lambda重写为一个保存值的类,以及一个主体与lambda主体相同的方法,尽管它将使用在此新类中捕获的值,而不是原始的方法调用。
堆分配查看器插件的意思是,在运行时这里发生了隐藏分配-正在分配此新的编译器生成的类,分配了值并调用了方法。
插件告诉您id
正在捕获和分配此新类-在lambda中这很明显,因为您在代码中看到了它。但是您也正在捕获this
,因为它GetTicket_uncached
是一个实例方法而不是静态方法。没有this
,您将无法调用实例方法,因此id
和this
都将在编译器生成的类中被捕获和分配。
您无法摆脱id
变量的分配,但是this
如果您将其GetTicket_uncached
设为静态,则可以摆脱引用(但这可能需要传入ServiceAddress
,在这种情况下,堆分配查看器会告诉您您正在关闭分配现在id
和ServiceAddress
)。
您可以在ReSharper帮助页面中看到有关“隐式捕获关闭”警告的更多详细信息。在讨论不同的场景和警告消息时,有关分配类以捕获变量的背景详细信息很有用。
- 2 回答
- 0 关注
- 174 浏览
添加回答
举报