c# - 是否可以在程序退出时强制 C# 终结器在 .NET Core 中运行?
问题描述
我有一个 .NET Core C# 类,它包装了一个非托管指针,它应该在程序退出时与其他资源清理一起被释放。但是,没有调用析构函数。我在调试和发布模式下都试过了。我看到 .NET Core 显然不能保证会运行析构函数,那么推荐的解决方法是什么?IMO 垃圾收集的主要目的是避免让开发人员跟踪引用,所以我觉得这种行为令人惊讶,至少可以这么说。
来自 MSDN:在 .NET Framework 应用程序中(但不在 .NET Core 应用程序中),程序退出时也会调用终结器。
public Demo {
IntPtr _ptr;
public Demo()
{
Console.WriteLine("Constructor");
_ptr = /* P-invoke external function */
~Demo
{
Console.WriteLine("Destructor");
/*P-invoke ptr deletion */
}
}
public static void Main()
{
Demo demo = new Demo();
demo = null;
GC.Collect();
}
程序输出:
Constructor
<...>\Test.exe (process 7968) exited with code 0.
解决方案
需要进行更多更改以提高调用终结器的可能性。
顺便说一句,Finalizer 永远不能保证被调用。如果要保证资源释放,请在应用/方法/代码块退出前实现IDisposable
并调用。Dispose()
此外,确保在退出代码块、使用或语句Dispose()
之前调用(即使应用程序崩溃,FailFast 和 StackOverflow 除外) 。try-finally
using
这是一个可以玩的例子。
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("[main] Constructing");
MyDisposable m = new MyDisposable(0);
MyMethod(1);
Console.WriteLine("[main] Disposing [object 0]");
m.Dispose();
Console.WriteLine("[main] GC Collecting");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("[main] Done");
Console.ReadKey();
}
private static void MyMethod(int i)
{
new MyDisposable(i);
}
}
public class MyDisposable : IDisposable
{
private int _id;
public MyDisposable(int id)
{
_id = id;
Console.WriteLine($"[object {_id}] Constructed");
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Console.WriteLine($"[object {_id}] Disposing by Dispose()");
}
else
{
Console.WriteLine($"[object {_id}] Disposing by ~Finalizer");
}
Console.WriteLine($"[object {_id}] Disposed");
disposed = true;
}
else
Console.WriteLine($"[object {_id}] Already disposed!");
}
~MyDisposable()
{
Dispose(false);
}
}
输出
[main] Constructing
[object 0] Constructed
[object 1] Constructed
[main] Disposing [object 0]
[object 0] Disposing by Dispose()
[object 0] Disposed
[main] GC Collecting
[object 1] Disposing by ~Finalizer
[object 1] Disposed
[main] Done
一些阅读:使用实现 IDisposable 的对象。
推荐阅读
- r - rlang,fpp3 R 包:错误:`vars` 在调用 aggregate_key() 时必须是字符向量
- asp.net-mvc - 如何在 ASP NET Web 项目中创建视频聊天
- node.js - 使用 docker-compose 构建并使用 docker run 运行 app 和 mongo
- javascript - Get all elments that have children arrays in javascript
- javascript - My app can't find my TypeScript package downloaded from the NPM registry (module not found)
- java - 消息编码可能出错
- python - 将持续时间(作为 int)添加到时间(作为对象)
- java - 如果列表发生唯一约束错误,Spring 不会回滚。如何为整个列表启用回滚?
- c++ - 在 C++ 中的多个类中使用模板类
- mysql - Sequelize - 如何在模型中定义触发器?