Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在单独的线程上捕获AccessViolationException_C#_Pinvoke - Fatal编程技术网

C# 在单独的线程上捕获AccessViolationException

C# 在单独的线程上捕获AccessViolationException,c#,pinvoke,C#,Pinvoke,我正在调用一个可能不稳定的本机库,我想确保我的C应用程序能够经受住潜在的AccessViolationException。我在我的App.config中找到了一种捕获异常的方法。由于崩溃发生在一个我不关心的单独线程上(我不关心它是否死亡),所以让我的应用程序运行安全吗?如果没有,是否有任何机制允许我对本机代码进行沙箱处理以防止崩溃 我不只是想记录崩溃,我真的在努力生存AccessViolationException 我尝试过在另一个AppDomain中执行代码,但没有真正的帮助,因为它在同一个进

我正在调用一个可能不稳定的本机库,我想确保我的C应用程序能够经受住潜在的
AccessViolationException
。我在我的
App.config
中找到了一种捕获异常的方法。由于崩溃发生在一个我不关心的单独线程上(我不关心它是否死亡),所以让我的应用程序运行安全吗?如果没有,是否有任何机制允许我对本机代码进行沙箱处理以防止崩溃

我不只是想记录崩溃,我真的在努力生存
AccessViolationException

我尝试过在另一个
AppDomain
中执行代码,但没有真正的帮助,因为它在同一个进程中运行。我也已经有了一个备份解决方案,它依赖于一个新的
进程
,以及一个IPC通道进行通信,但这很难维护和调试。如果我能在主流程中这样做,事情就会简化很多

如果要创建一个测试环境,只需创建一个简单的Win32库,其中包含一个导致崩溃的函数(
AccessViolationException

C标题:

void do_crash()
{
    int *b = NULL;
    int c = b[3000];
}
[DllImport("CrashLib.dll", EntryPoint = "do_crash")]
extern static void DoCrash();

static void Main(string[] args)
{   
    ExecuteSandboxed(delegate
    {
        DoCrash();
    });

    // Even if there's a AccessViolationException, I can keep going

    Console.ReadLine();
}

private static void ExecuteSandboxed(Action action)
{
    try
    {
        Task.Run(action).Wait();
        Console.WriteLine("Success");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
uu declspec(dllexport)void do_crash()

C来源:

void do_crash()
{
    int *b = NULL;
    int c = b[3000];
}
[DllImport("CrashLib.dll", EntryPoint = "do_crash")]
extern static void DoCrash();

static void Main(string[] args)
{   
    ExecuteSandboxed(delegate
    {
        DoCrash();
    });

    // Even if there's a AccessViolationException, I can keep going

    Console.ReadLine();
}

private static void ExecuteSandboxed(Action action)
{
    try
    {
        Task.Run(action).Wait();
        Console.WriteLine("Success");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
C#来源:

void do_crash()
{
    int *b = NULL;
    int c = b[3000];
}
[DllImport("CrashLib.dll", EntryPoint = "do_crash")]
extern static void DoCrash();

static void Main(string[] args)
{   
    ExecuteSandboxed(delegate
    {
        DoCrash();
    });

    // Even if there's a AccessViolationException, I can keep going

    Console.ReadLine();
}

private static void ExecuteSandboxed(Action action)
{
    try
    {
        Task.Run(action).Wait();
        Console.WriteLine("Success");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
简而言之,例外情况 异常背后最基本的想法是说“这无法完成”,并防止应用程序继续处于损坏状态。当引发异常时,它通常允许应用程序当前情况并继续执行。这是通过倒带调用堆栈并查找异常处理程序(
try-catch
blocks)来完成的

例外情况可能来自3个主要来源:

  • 应用程序本身(使用
    抛出…
  • 操作系统异常,例如
    FileNotFoundException
  • CPU异常,例如
    除以零异常
    (由于ALU无法执行此类计算而引发)
到目前为止,最可怕的异常是CPU引发的异常,因为它们可以使CPU处于无效状态

此外,例外情况可分为三类:

  • 无效操作-当应用程序尝试执行无效操作时,会引发此类异常。诸如访问不存在的文件、除以零等操作
  • 无效线程状态-当给定线程的状态损坏时,会引发此类异常。运行时堆栈损坏等情况可能是原因之一
  • 无效进程(应用程序)状态-当整个应用程序处于无效状态时,会引发此类异常。内存不足就是一个很好的例子
每种异常都比以前的异常更严重。第一个将终止当前过程并启动调用堆栈倒带。第二个线程将终止整个线程。最后一个将终止整个应用程序

注意:终止过程要复杂得多,例外情况并没有真正分为三类

理解
AccessViolationException
现在我们已经对异常有了基本的了解,我们可以预测
AccessViolationException
将使我们的应用程序处于何种状态

首先,谁抛出异常?这是一个有点诡计的问题*但实际上,当操作系统意识到地址尚未分配给进程时,就会抛出异常

这是什么类型的异常?因为异常与线程或应用程序的状态无关;我们只是试图访问“不存在的”内存(就像我们可能试图访问不存在的文件一样)。这显然是一个
无效操作
异常


AccessViolationException
是操作系统中的一个无效操作异常。
现在我们知道,只要我们确定没有使CPU状态、应用程序状态或线程状态无效,就可以安全地继续执行;我们只是试图做一些非法的事情。

@Isun我知道如何处理它们,我想知道继续这样做是否安全,如果不安全,是否还有其他方法可以继续安全。文章()详细解释了这个想法,但总的来说,继续这样做是安全的,因为主线程的堆栈将保持干净。与
OutOfMemoryException
不同,
AccessViolationException
对整个应用程序来说不是致命的。非常好!你应该将此作为答案发布。。