强制垃圾收集或反映到私人领域,这是不是很邪恶?

Yau*_*aur 12 .net c# reflection garbage-collection private-members

我们有一个第三方库,内部使用SafeHandle来处理非托管资源.在某些错误情况下,必须处理对象并重新创建它.但是,dispose实现中存在一个错误,阻止Handle在这些情况的子集中被关闭.这可以防止在终结器运行之前成功创建新对象.

在我们可以修复第三方代码之前,已经提出了两个解决方案(两者都是邪恶的)来处理这个问题:

  1. 运行a GC.Collect以使终结器运行并清理对象

  2. 如果处理失败,请使用反射来处理Handle并关闭它

哪一个不那么邪恶,为什么?还有一些我们没有考虑过的方法比其中任何一种方法都不那么邪恶吗?

Cod*_*aos 14

我赞成私人反思.这是一个本地化的bug,所以解决方案也应该是本地的.而且你的代码打算做的更清楚.并且你可能会添加一些测试,一旦修复了bug就会注意到.因此,一旦不再需要,就可以轻松删除黑客攻击.

...
thirdPartyObject.Dispose();
ThirdPartyDisposeBugWorkaround(thirdPartyObject);
...

void ThirdPartyDisposeBugWorkaround(ThirdPartyClass thirdPartyObject)
{
   //Do private reflection here
}
Run Code Online (Sandbox Code Playgroud)

另一方面,强制GC具有全局效应.干扰GC的原因很多(其中大部分都是坏的).你的代码所做的事情就不那么明显了.因此,即使修复了错误,也可以保留调用.

Old New Thing:不要使用全局状态来管理本地问题

  • 一千次同意.调用`GC.Collect`几乎总是错误的做法.链接到Raymond博客的奖励积分.但无论你决定什么,重要的是**广泛地记录**. (3认同)

Sam*_*eff 5

我会考虑反思,但要确保你有错误处理,这明确表明错误是什么,记住错误可能直到现在几年才被触发,你的开发团队可能已经翻过来,没有人记得这个古怪的黑客.

try
{
   .. hacky reflection ..
}
catch(Exception ex)
{
    throw new Exception("Reflection on private field 'Xyz' of 3rd Party Component 'Abc' failed.  Was 'Abc' updated? Reflection is used due to bug in 'Dispose' implementation.", ex);
}
Run Code Online (Sandbox Code Playgroud)