在多个例程之间使用try-catch

本文关键字:try-catch 之间 例程 | 更新日期: 2023-09-27 18:01:53

这有点像我之前问过的一个问题的后续,尽管我现在能够提供更多的代码来改进我的问题,并进一步显示我在这方面的问题。

这里有三个例程。其中两个例程一起工作,如果成功,将使用System.Reflection将程序集加载到内存中。如果文件没有正确加载到内存中,我希望这些例程返回一个错误,但是由于某些原因,这些try-catch语句根本不会按我想要的方式工作。

注意:要使这个例程工作,该文件必须是。net程序集。例如,如果文件是用VB6编写的,就会抛出一个错误。这是我试图返回给我的错误。

private void ExecuteDataIntoMemory(string filePath)
{
    byte[] bytes = File.ReadAllBytes(filePath);
    try
    {
        ExecFile(bytes);
        MessageBox.Show("successfully loaded this file into memory");
    }
    catch
    {
        MessageBox.Show("Could not load this file into memory");
    }
}
private static void ExecFile(byte[] data)
{
    try
    {
        //Work around for "SetCompatibleTextRenderingDefault"  
        System.Threading.Thread T = new System.Threading.Thread(ExecFile);
        //Set STA to support drag/drop and dialogs?
        T.SetApartmentState(System.Threading.ApartmentState.STA);
        T.Start(data);
    }
    catch
    {
        MessageBox.Show("caught some error ...");
    }
}
private static void ExecFile(object o)
{
        System.Reflection.MethodInfo T = System.Reflection.Assembly.Load((byte[])o).EntryPoint;
        if (T.GetParameters().Length == 1)
            T.Invoke(null, new object[] { new string[] { } });
        else
            T.Invoke(null, null);

}

如果有必要,我可以澄清更多,但我不确定在这一点上还需要包括哪些其他信息。

在多个例程之间使用try-catch

在ExecFile的catch语句中使用"throw"语句来引发在ExecFile中捕获的相同的"异常"(或错误)。例如:

 catch {
      throw;
 }
我想我找到了问题所在。ExecFile(byte[])启动线程并立即返回,无需等待线程退出。要允许该方法等待线程退出,请添加:
 T.Join();
在启动线程后立即

。(但是,为了避免可能的歧义,您应该重命名ExecFile(object)。我也不确定ExecFile(byte[])是否会捕获ExecFile(object)的异常。

如果我没理解错的话,您希望ExecuteDataIntoMemory只有在ExecFile成功时才被评估。

1-你正在运行一个新线程来执行ExecFile方法,该方法将在另一个线程中执行。因此,首先在ExecFile(byte[] data)try块上运行ExecFile(data),而不需要一个新线程,因为您想以任何方式等待它:

try
{
    ExecFile(data);
}

2-请注意,您有两个方法具有相同的名称'ExecFile(byte[] data)'和ExecFile(object o),您传递的数据来自byte[]类型,因此它将是无限递归的,或者直到堆栈溢出异常引发。所以你应该将data转换为object,然后传递给方法,即:

try
{
    ExecFile((object)data);
}

3-在ExecFile(byte[] data)方法的catch块处重新抛出异常,以便它可以从调用者方法2中处理,即:

try
{
    ExecFile((object)data);
}
catch
{
    MessageBox.Show("caught some error ...");
    throw;
}

如果你在ExecFile(byte[] data)中捕获异常,它将不会在你的父方法(ExecuteDataIntoMemory(string filePath))中传播,然后将不会再次被捕获

如果你真的需要捕获你的异常两次,重写你的子方法如下

private static void ExecFile(byte[] data)
{
    try
    {
        //Work around for "SetCompatibleTextRenderingDefault"  
        System.Threading.Thread T = new System.Threading.Thread(ExecFile);
        //Set STA to support drag/drop and dialogs?
        T.SetApartmentState(System.Threading.ApartmentState.STA);
        T.Start(data);
    }
    catch (Exception ex)
    {
        MessageBox.Show("caught some error ...");
        throw ex;
    }
}

如果没有,则简单地不要在此方法中出现try..catch错误,并且异常将被传播。

只是在callstack中查看哪个方法再次调用executedataintommemory方法?

如果您使用的是Visual studio IDE,请在消息框处设置一个断点:

   MessageBox.Show("successfully loaded this file into memory");

然后简单地转到视图菜单,从那里找到callstack窗口来显示和查看callstack(显示外部代码到callstack)

也许这能帮上忙。

  1. (我认为)粗略的方法是订阅

    ,但对你的情况应该有效。

    AppDomain.CurrentDomain.UnhandledException

事件,它将直接从函数ExecFile(object o);

引发异常。
  1. 或者在ExecFile(object o);方法中创建一个设置为NEGATIVE状态的状态机

  2. 或者不要在多线程中这样做:)