Семафор Howto Guarantee, выпущенный при прерывании потока или остановленном процессе в веб-приложении asp.net в Azure - PullRequest
0 голосов
/ 20 октября 2019

Я хочу быть в состоянии гарантировать, насколько это возможно, освобождение семафора, когда веб-приложение IIS (работающее в домене приложения) закрыто или принудительно завершено - либо «Диспетчер задач - завершение задачи», либо IISпереработка пула приложений. В Azure с моей конфигурацией среды S1 сохранение новой конфигурации приложения приводит к завершению процесса w3wp.exe, на котором работает веб-сайт, и запуск нового процесса w3wp для веб-приложения. Мне нужно убедиться, насколько это возможно, что процесс, завершающий работу, освобождает захваченный семафор. Приведенный ниже код демонстрирует наилучшие текущие усилия - я хотел бы знать, может ли кто-нибудь предложить улучшения - с четким объяснением того, почему это будет улучшение.

Ниже приведен мой текущий код:

    //CriticalFinalizerObject - seems to be the best option for releasing a semaphore
    //on forced app domain unload or thread abort.
    ///5485846/avtomaticheskoe-osvobozhdenie-semafora-pri-vyhode-iz-protsessa
    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
            }
        }
    }
...