我希望能够尽可能地保证关闭(或在App Domain中运行)IIS Web App或被迫退出时(通过“任务管理器-结束任务”或IIS回收)释放信号量。应用程序池。在具有我的环境配置S1的Azure上,保存新的App Config将导致网站正在运行的w3wp.exe进程退出,并为Web应用程序启动一个新的w3wp进程。我需要尽可能确保关闭的进程释放捕获的信号量。下面的代码显示了当前的最佳努力-我想知道是否有人可以提出改进建议-清楚说明为什么会有改进。
以下是我当前的代码:
//CriticalFinalizerObject - seems to be the best option for releasing a semaphore
//on forced app domain unload or thread abort.
//https://stackoverflow.com/questions/5231569/automatic-semaphore-release-on-process-exit
public class SystemSemaphoreReleaser : CriticalFinalizerObject, IDisposable
{
private readonly Semaphore _semaphore;
internal SystemSemaphoreReleaser(Semaphore semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // finalize will not run
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
_semaphore.Release();
}
catch { }
finally
{
try
{
_semaphore.Dispose();
}
catch { }
}
}
}
~SystemSemaphoreReleaser()
{
try
{
// This is only called when the thread did not exit normally.
// It is a full backup for dispose NOT being called.
// Dispose would normally be called with false here to only clean up unmanaged resources - but the semaphore needs to be released.
// Note: The semaphore Release method is marked with
// [PrePrepareMethod] and
// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] so is fine to be called in a CER (constrained execution region).
// Garbage Collection will run when an AppDomain is being unloaded.
Dispose(true);
}
catch
{
// we do NOT want the finalizer to throw - never ever
}
}
}
正如MSDN所说的>
[在大多数情况下,您无需编写从CriticalFinalizerObject类。 .NET Framework类库提供
.NET中的SafeHandle
和CriticalHandle
这两个类关键的终结处理功能。
Semaphore
类继承WaitHandle
,它具有表示本机操作系统句柄的SafeWaitHandle
属性。SafeWaitHandle
已经继承了CriticalFinalizerObject
类,因此您无需手动继承它,因为
中CLR保证将提供所有关键的最终代码即使在CLR强行的情况下,也有执行的机会卸载应用程序域或中止线程。
因此,如果发生任何崩溃,CLR将释放本机OS句柄,则您在这里做了一些工作,
Release
在大多数情况下,信号量就足够了,您无需在此处实现额外的终结处理。另外,您只需要实现自己的终结器即可处理非托管资源,但是您的示例中没有任何终结器,非托管资源已经包装在SafeWaitHandle