0

我们目前正在开发一个具有开放 C# API 接口的程序。现在,假设您有以下 C# 脚本:

int[] Test = { 0, 3 };

private void Test()
{
    Debug.Log(Test[4].ToString()); //Exception!!
}

但是,如果我们现在尝试编译,InvokeTest Void会失败。它显然应该失败,但我们想捕获异常,所以我们的整个应用程序不会冻结。

Assembly assembly = Assembly.LoadFrom("C:/Our/Path/To/Dll.dll");

Type type = assembly.GetType("ClassApplication1.Test");
object instance = Activator.CreateInstance(type);

type.InvokeMember("Test",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreReturn,
null,
instance,
null);

如果我们正在调试,此弹出窗口将出现在 Visual Studio 2012 中,如果不调试我们的应用程序只会完全崩溃。

nn

nn

//编辑:

我知道这Debug.Log(Test[4].ToString()); //Exception!!是错误的,并且会调用异常(!!!)。它被通缉了。将 try {} 块通过它会起作用,但请记住,脚本是第 3 方制作的。我没有这方面的手,但至少我不希望我们的应用程序正在吃错误(并将它们显示在 RichTextBox 中),而不是抛出它们(=应用程序崩溃)。

TLDR:我想防止我加载到我的程序集中以使我的程序崩溃的第 3 方程序集

4

2 回答 2

2

如果我理解它,您只需要捕获以下引发的异常InvokeMember

try
{
    type.InvokeMember("Test", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreReturn, null, instance, null);
}
catch(TargetInvocationException e)
{
    // e.InnerException will be IndexOutOfRangeException in your example
}
catch(Exception e)
{  // one of the other exceptions
}

有关可能导致第二个块的所有可能异常,请参阅MSDN 。您可能只想将所有代码(从加载程序集开始)包装在一个 try 块中,因为这些代码也可能会失败。

您还应该调查AppDomains,它们是像这样进行隔离的“正确”方法。它们连接到 CLR 以提供比您自己可能管理的更多的保护。

于 2013-09-06T23:40:58.127 回答
0
int[] Test = { 0, 3 };

此行将Test数组大小设置为 2,因此您可以从中获取的唯一项目是:

Test[0] // == 0
Test[1] // == 3

这就是Debug.Log(Test[4].ToString());引发异常的原因。

要捕获它,您必须在调用方法时使用try/catch阻塞:Test

try
{
    Test();
}
catch(IndexOutOfRangeException ex)
{
    Console.WriteLine("Exception caught: {0}", ex.Message);
}
于 2013-09-06T18:28:31.750 回答