我们目前正在开发一个具有开放C#API接口的程序。现在,假设您有以下C#脚本:
int[] Test = { 0, 3 };
private void Test()
{
Debug.Log(Test[4].ToString()); //Exception!!
}
编译工作,但是,如果我们现在尝试Invoke
Test 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中,而不调试我们的应用程序只是完全崩溃。
//编辑:
我知道Debug.Log(Test[4].ToString()); //Exception!!
是错误的并且会调用异常(!!!)。它被通缉。通过try {}块来实现,但请记住脚本是第三方制作的。我没有掌握这一点,但至少我不知道我们的应用程序正在处理错误(并在richTextBox中显示它们),而不是抛出它们(=应用程序崩溃)。
TLDR:我想阻止加载到我的程序集中的第三方程序集使我的程序崩溃
答案 0 :(得分: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以提供比您自己可能管理的更多保护。
答案 1 :(得分: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);
}