Way*_*ner 6 .net atexit equivalent
在C那里有atexit功能,它
atexit()函数通过exit(3)或通过程序main()的返回来注册在正常进程终止时调用的给定函数.
Python具有类似的功能.
.NET是否提供了在正常进程终止时调用代码的方法?我知道有像某些事情DomainUnload和ProcessExit,但至少据我所知,这是不可靠的-要么要求应用程序是Windows窗体(或WPF应用程序),或别的东西.我正在为.dll编写代码,所以我不能依赖于像主程序函数那样的东西 - 将它包装在try/catch中.
我的最终目标是执行一些文件清理(即刷新缓冲区和关闭).如果我可以调用一些非托管代码,例如win32api钩子或其他什么东西,我对此完全没问题.
我知道没有直截了当的答案.
如果要编写健壮的DLL,则应准备好以下几种方案:
第三种情况是最难处理的,因为CLR可以被其主机禁用,因此托管代码将不再执行.
System.Windows.Forms.Application.ApplicationExit 是不好的,因为它只适用于WinForm应用程序.
System.AppDomain.DomainUnload 本身并不好,因为永远不会为默认的AppDomain引发它.
AppDomain.ProcessExit 本身并不好:如果您的代码托管在单独的AppDomain中,主机可能会卸载该AppDomain,因此该事件永远不会引发.
我首先尝试使用以下内容覆盖大多数情况:
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
AppDomain.CurrentDomain.ProcessExit += MyTerminationHandler;
else
AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler;
Run Code Online (Sandbox Code Playgroud)
但请注意以下注释(来自MSDN):
所有ProcessExit事件处理程序的总执行时间都是有限的,就像所有终结器的总执行时间在进程关闭时受到限制一样.默认值为两秒.非托管主机可以通过使用OPR_ProcessExit枚举值调用ICLRPolicyManager :: SetTimeout方法来更改此执行时间.
上面的代码仍然无人看管第三种情况.我知道有两种处理该场景的方法(以及前两种)
首先,您可以使用该System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup方法,如下所示:
{
// this goes at your code's entry point
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(MyExecutionCode, MyCleanupCode, null);
}
static void MyExecutionCode(object data) { /* your execution code here */}
static void MyCleanupCode(object data, bool exceptionThrown) { /* your cleanup code here */ }
Run Code Online (Sandbox Code Playgroud)
其次,您可以通过继承它并将清理代码放在终结器中来利用System.Runtime.ConstrainedExecution.CriticalFinalizerObject该类(请参阅此处的MSDN).这要求您的清理代码遵守约束执行区指南.
| 归档时间: |
|
| 查看次数: |
1577 次 |
| 最近记录: |