How to handle AccessViolationException

后端 未结 5 1773
暖寄归人
暖寄归人 2020-11-22 06:53

I am using a COM object (MODI) from within my .net application. The method I am calling throws a System.AccessViolationException, which is intercepted by Visual Studio. Th

5条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-11-22 07:31

    Microsoft: "Corrupted process state exceptions are exceptions that indicate that the state of a process has been corrupted. We do not recommend executing your application in this state.....If you are absolutely sure that you want to maintain your handling of these exceptions, you must apply the HandleProcessCorruptedStateExceptionsAttribute attribute"

    Microsoft: "Use application domains to isolate tasks that might bring down a process."

    The program below will protect your main application/thread from unrecoverable failures without risks associated with use of HandleProcessCorruptedStateExceptions and

    public class BoundaryLessExecHelper : MarshalByRefObject
    {
        public void DoSomething(MethodParams parms, Action action)
        {
            if (action != null)
                action();
            parms.BeenThere = true; // example of return value
        }
    }
    
    public struct MethodParams
    {
        public bool BeenThere { get; set; }
    }
    
    class Program
    {
        static void InvokeCse()
        {
            IntPtr ptr = new IntPtr(123);
            System.Runtime.InteropServices.Marshal.StructureToPtr(123, ptr, true);
        }
    
        private static void ExecInThisDomain()
        {
            try
            {
                var o = new BoundaryLessExecHelper();
                var p = new MethodParams() { BeenThere = false };
                Console.WriteLine("Before call");
    
                o.DoSomething(p, CausesAccessViolation);
                Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); //never stops here
            }
            catch (Exception exc)
            {
                Console.WriteLine($"CSE: {exc.ToString()}");
            }
            Console.ReadLine();
        }
    
    
        private static void ExecInAnotherDomain()
        {
            AppDomain dom = null;
    
            try
            {
                dom = AppDomain.CreateDomain("newDomain");
                var p = new MethodParams() { BeenThere = false };
                var o = (BoundaryLessExecHelper)dom.CreateInstanceAndUnwrap(typeof(BoundaryLessExecHelper).Assembly.FullName, typeof(BoundaryLessExecHelper).FullName);         
                Console.WriteLine("Before call");
    
                o.DoSomething(p, CausesAccessViolation);
                Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); // never gets to here
            }
            catch (Exception exc)
            {
                Console.WriteLine($"CSE: {exc.ToString()}");
            }
            finally
            {
                AppDomain.Unload(dom);
            }
    
            Console.ReadLine();
        }
    
    
        static void Main(string[] args)
        {
            ExecInAnotherDomain(); // this will not break app
            ExecInThisDomain();  // this will
        }
    }
    

提交回复
热议问题