我们目前正在开发一个具有开放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 2012中,而无需调试我们的应用程序就会完全崩溃。


//编辑:
我知道Debug.Log(Test[4].ToString()); //Exception!!是错误的,并将调用excetpion (!)。是被通缉的。尝试{}块将工作,但请记住,脚本是由第三方制作的。我没有掌握这一点,但至少我不认为我们的应用程序正在吞噬错误(并将它们显示在richTextBox中),而不是抛出它们(=应用程序崩溃)。
TLDR:我希望防止第三方程序集加载到程序集中,从而使程序崩溃。
发布于 2013-09-06 23:40:58
如果我理解它,您只需捕获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-06 18:28:31
int[] Test = { 0, 3 };这一行将Test数组大小设置为2,因此您可以从中获取的唯一项目是:
Test[0] // == 0
Test[1] // == 3这就是为什么Debug.Log(Test[4].ToString());抛出异常的原因。
要捕获它,必须在调用try方法时使用Test /catch块:
try
{
Test();
}
catch(IndexOutOfRangeException ex)
{
Console.WriteLine("Exception caught: {0}", ex.Message);
}https://stackoverflow.com/questions/18664133
复制相似问题