Различное исключение поврежденного состояния AppDomain (AccessViolationException) Рабочий пул приложений - PullRequest
0 голосов
/ 16 октября 2018

Как я могу предотвратить сбой всего приложения (процесса), когда AccessViolationException (или другое исключение поврежденного состояния) генерируется в домене приложения в .NET 4.6?Моя цель - обернуть стороннюю библиотеку (считыватель штрих-кода GdPicture.NET) в свой домен приложений, который периодически прерывает рабочий процесс IIS в соответствии с аварийными дампами IIS.Другими словами, я хотел бы изолировать сторонний библиотечный вызов в своем собственном домене приложений, чтобы он мог не работать внутри самого себя, не отключая весь веб-сайт.

В приведенном ниже примере кода, если я неt использовать атрибут HandleProcessCorruptedStateExceptions. Я не могу перехватить AccessViolationException (обернутый в TargetInvocationException), который создается в другом домене приложения (в ClassLibrary1.dll).Если я украсил HandleProcessCorruptedStateExceptions (только для 2-го вызова AppDomain), безопасно ли продолжать основной процесс или он перешел в нестабильное состояние?

Решение Visual Studio с двумя проектами (консольное приложение и класс)библиотека).

enter image description here

using System;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Security;

namespace StackOverflowQuestion
{
    class Program
    {
        static void Main(string[] args)
        {
            new Tester().RunTest();
        }
    }

    class Tester
    {
        public void RunTest()
        {
            var myTestAppDomain = AppDomain.CreateDomain("My Test AppDomain");
            var loader = (Loader)myTestAppDomain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
            TestHandleProcessCorruptedStateExceptions(loader, myTestAppDomain);

            // how can I make sure process doesn't crash when AppDomain "My Test AppDomain" crashes
            Console.WriteLine("This won't be written to console unless [HandleProcessCorruptedStateExceptions] attribute is present...");

            // keep console window open
            Console.ReadKey();
        }

        // [HandleProcessCorruptedStateExceptions, SecurityCritical]
        private void TestHandleProcessCorruptedStateExceptions(Loader loader, AppDomain appDomain)
        {
            Console.WriteLine("Loading 3rd party lib ClassLibrary1.dll...");
            loader.LoadAssembly(@"..\..\..\ClassLibrary1\bin\debug\ClassLibrary1.dll");
            try
            {
                // executing static method in dummy 3rd party dll in a different app domain (named "My Test AppDomain")
                loader.ExecuteStaticMethod("ClassLibrary1.Class1", "DoStuff", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString());
            }
            catch (TargetInvocationException)
            {
                AppDomain.Unload(appDomain);
                Console.WriteLine("DoStuff failed. This won't be written to console  unless [HandleProcessCorruptedStateExceptions] attribute is present...");
            }
        }
    }

    class Loader : MarshalByRefObject
    {
        private Assembly _assembly;

        public void LoadAssembly(string path)
        {
            _assembly = Assembly.Load(AssemblyName.GetAssemblyName(path));
        }

        public object ExecuteStaticMethod(string typeName, string methodName, params object[] parameters)
        {
            var type = _assembly.GetType(typeName);
            // assume there is no overloads for simplicity
            var method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public);

            return method.Invoke(null, parameters);
        }
    }
}

И это код в Class1.cs в проекте ClassLibrary1:

using System;
using System.Runtime.InteropServices;

namespace ClassLibrary1
{
    public class Class1
    {
        public static void DoStuff(string msg)
        {
            Console.WriteLine("Throwing AccessViolationException now...");

            // throw an AccessViolationException which cannot be caught in a try/catch block
            FakeAccessViolationException();

            Console.WriteLine("Class1.DoStuff: " + msg);
        }

        private static void FakeAccessViolationException()
        {
            var ptr = new IntPtr(42);
            Marshal.StructureToPtr(42, ptr, true);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...