如何保证线程中止时释放的信号量或在Azure上的asp.net Web应用程序中杀死的进程

问题描述 投票:0回答:1

我希望能够尽可能地保证关闭(或在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
            }
        }
    }
c# asp.net semaphore appdomain thread-abort
1个回答
0
投票

正如MSDN所说的>

[在大多数情况下,您无需编写从CriticalFinalizerObject类。 .NET Framework类库提供SafeHandleCriticalHandle这两个类关键的终结处理功能。

.NET中的

Semaphore类继承WaitHandle,它具有表示本机操作系统句柄的SafeWaitHandle属性。 SafeWaitHandle已经继承了CriticalFinalizerObject类,因此您无需手动继承它,因为

CLR保证将提供所有关键的最终代码即使在CLR强行的情况下,也有执行的机会卸载应用程序域或中止线程。

因此,如果发生任何崩溃,CLR将释放本机OS句柄,则您在这里做了一些工作,Release在大多​​数情况下,信号量就足够了,您无需在此处实现额外的终结处理。另外,您只需要实现自己的终结器即可处理非托管资源,但是您的示例中没有任何终结器,非托管资源已经包装在SafeWaitHandle

SafeWaitHandle MSDN参考,WaitHandleMSDN参考

© www.soinside.com 2019 - 2024. All rights reserved.