- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在使用供应商库时遇到了一些问题,有时库计算出的实体应该始终包含有效数据时为空。
功能代码(与供应商调试问题后)大致如下:
Task.Factory.StartNew(() => ValidateCalibration(pelRectRaw2Ds, crspFeatures, Calibration.Raw2DFromPhys3Ds));
.....
private void ValidateCalibration(List<Rectangle> pelRectRaw2Ds, List<List<3DCrspFeaturesCollection>> crspFeatures, List<3DCameraCalibration> getRaw2DFromPhys3Ds)
{
var calibrationValidator = new 3DCameraCalibrationValidator();
// This is required according to vendor otherwise validationResultsUsingRecomputedExtrinsics is occasionally null after preforming the validation
GC.SuppressFinalize(calibrationValidator);
3DCameraCalibrationValidationResult validationResultUsingOriginalCalibrations;
3DCameraCalibrationValidationResult validationResultsUsingRecomputedExtrinsics;
calibrationValidator.Execute(pelRectRaw2Ds, crspFeatures, getRaw2DFromPhys3Ds, out validationResultUsingOriginalCalibrations, out validationResultsUsingRecomputedExtrinsics);
Calibration.CalibrationValidations.Add(new CalibrationValidation
{
Timestamp = DateTime.Now,
UserName = Globals.InspectionSystemObject.CurrentUserName,
ValidationResultUsingOriginalCalibrations = validationResultUsingOriginalCalibrations,
ValidationResultsUsingRecomputedExtrinsics = validationResultsUsingRecomputedExtrinsics
});
}
验证过程是一个相当耗时的操作,所以我将它交给了一个任务。我遇到的问题是,最初我没有调用 GC.SuppressFinalize(calibrationValidator) 并且当应用程序从发布版本运行时,输出参数 validationResultsUsingRecomputedExtrinsics 将为空。如果我从调试版本运行应用程序(附加或不附加调试器),则 validationResultsUsingRecomputedExtrinsics 将包含有效数据。
我不完全理解 GC.SuppressFinalize() 在这种情况下做了什么,或者它是如何解决问题的。我能找到的关于 GC.SuppressFinalize() 的所有信息都是在实现 IDisposable 时使用的。我在“标准”代码中找不到它的任何用途。
添加对 GC.SuppressFinalize(calibrationValidator) 的调用如何/为何解决此问题?
我知道如果不深入了解供应商库的内部结构,可能无法确定,但任何见解都会有所帮助。
该应用程序使用 VS2012 编译,面向 .NET 4.0。该供应商库要求在 app.config 中指定 useLegacyV2RuntimeActivationPolicy="true"选项。
这是我从供应商那里收到的理由:
The SuppressFinalize command makes sure that the garbage collector will not clean something up “early”. It seems like for some reason your application was sometimes having the garbage collector get a bit zealous and clean up the object before you were truly done with it; it is almost certainly scope related and possibly due to the multi-threading causing confusion on the scope of the calibrationValidator. Below is the response I got from Engineering.
Because the variable was created in the local scope, and that function runs in the background thread, Garbage Collection runs in the main thread, and it seems that the Garbage collection is not smart enough in handling multi-thread situations. Sometimes, it just releases it too early (internal execution of validator not finished yet, and still needs this variable).
最佳答案
这很可能是解决过早垃圾收集问题的黑客攻击。非托管代码并不少见,在相机应用程序中很典型。这不是一个健康的 hack,很有可能因为终结器不执行而导致资源泄漏。非托管代码的包装器几乎总是在终结器中做一些事情,它们需要释放非托管内存是很常见的。
问题在于,当非托管代码运行时,calibrationValidator 对象可能会被垃圾回收。在你的程序中有另一个线程使这成为可能,因为另一个线程可以分配对象并触发 GC。代码的所有者在测试时很容易错过这一点,要么是在使用多线程时从未测试过代码,要么只是运气不够好在错误的时间触发了 GC。
您这边的正确解决方法是确保抖动标记在调用之后使用的对象,这样垃圾收集器就不会收集它。您可以通过添加 GC.KeepAlive(calibrationValidator)
来实现在 Execute()
调用之后。
关于c# - 这种 GC.SuppressFinalize() 的使用感觉不对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15561025/
多次调用 GC.SuppressFinalize(object) 有什么缺点吗? protected Dispose(bool) 方法 dispose pattern 检查它之前是否被调用,但在公共(
我有几个问题无法得到正确的答案。 1) 当我们没有析构函数时,为什么要在 Dispose 函数中调用 SuppressFinalize。 2) Dispose 和 finalize 用于在对象被垃圾回
在 .NET 中 Task.Delay() 的引用源中,我遇到了 a snippet of code : // ... and create our timer and make sure that
Java 是否有相当于 .Net 的 GC.SuppressFinalize ? 在 .Net 中,SuppressFinalize 用于 dispose pattern避免 relatively h
我在实践中的观察是GC.SuppressFinalize并不总是抑制对终结器的调用。尽管如此,终结器可能还是被调用了。因此,我想知道 GC.SuppressFinalize 是否具有请求的性质,而不是
刚看完这篇文章,“Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework ”,作者 Jeffre
在.NET中,什么情况下应该使用GC.SuppressFinalize()? 使用这种方法给我带来了什么好处? 最佳答案 SuppressFinalize 只能由具有终结器的类调用。它通知垃圾收集器
因为 finalizer/IDisposable 和所谓的“IDisposable 模式”主题往往会引发大量故作姿态、武断和好战的观点(不是-分别是 here 、 here 、 here 等等),我真
我可以在同一个类中实现这两个方法吗? public class MyClass : IDisposable { // some implementation // if i missed to
有没有办法检测对象是否调用了 GC.SuppressFinalize? 我有一个看起来像这样的对象(为清楚起见省略了完整的 Dispose 模式): public class ResourceWrap
我为我的代码使用默认的 IDisposable 实现模板(模式)。 片段: public void Dispose() { Dispose(true); GC.SuppressFina
出于某种原因FXCop seems to think我应该在 Dispose 中调用 GC.SuppressFinalize,无论我是否有终结器。 我错过了什么吗?是否有理由在没有定义终结器的对象上调
我正在阅读“The C# Language”,第 4 版,它讨论垃圾收集如下: "BILL WAGNER: The following rule is an important difference
是的,我知道如何使用GC.SuppressFinalize() - 解释了here .我读过很多次使用 GC.SuppressFinalize() 从终结队列中删除对象,我认为这是好的,因为它使 GC
我在使用供应商库时遇到了一些问题,有时库计算出的实体应该始终包含有效数据时为空。 功能代码(与供应商调试问题后)大致如下: Task.Factory.StartNew(() => Valida
正如问题所述,我只是想知道,因为有人问过我,但我不知道,这有任何原因吗? 最佳答案 当一个类没有定义终结器(析构函数)时,在该类的实例上调用 SuppressFinalize() has no eff
有些类(例如 DataTable)已经在其构造函数中调用了 SuppressFinalize,因此没有必要在其上调用处置/使用。 (因为dispose是为了早点release但是没有release)
我有一个简单的类 MyDataClass,其成员 (obj) 实现了 IDisposable: public class MyDataClass : IDisposable { private
我刚刚实现了 Dispose 模式,当我刚刚键入 GC.SuppressFinalize(this) 行时,我想知道是否有使用 以外的东西的用例this 作为方法的参数。 这是典型的模式: publi
我有以下代码: public void Dispose() { if (_instance != null) { _instance = null; /
我是一名优秀的程序员,十分优秀!