0

这在某种程度上是对我之前提出的问题的跟进,尽管我现在能够提供更多代码来改进我的问题并进一步展示我在这方面的问题。

我这里有三个例程。其中两个例程一起工作 - 如果成功,将使用 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);


}

如有必要,我可以澄清更多,但我不确定此时要包括哪些其他信息。

4

5 回答 5

1

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

 catch {
      throw;
 }

我想我发现了问题所在。ExecFile(byte[]) 启动线程并立即返回,无需等待线程退出。要允许该方法等待线程退出,请添加:

 T.Join();

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

于 2011-07-10T14:38:39.390 回答
0

如果我很了解您,您希望仅在成功ExecuteDataIntoMemory时才对其进行评估。ExecFile

1-您正在运行一个新线程来执行ExecFile将在不同线程中执行的方法。所以首先在没有新线程的情况下运行try块,因为你想以任何方式等待它:ExecFile(byte[] data)ExecFile(data)

try
{
    ExecFile(data);
}

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

try
{
    ExecFile((object)data);
}

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

try
{
    ExecFile((object)data);
}
catch
{
    MessageBox.Show("caught some error ...");
    throw;
}
于 2011-07-10T15:00:42.313 回答
0

看看调用栈中哪个方法又调用了 ExecuteDataIntoMemory 方法?

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

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

然后简单地转到视图菜单,从那里找到要显示的调用堆栈窗口并查看调用堆栈(显示调用堆栈的外部代码)

也许这会有所帮助。

于 2011-07-10T15:03:22.633 回答
0

如果您在其中捕获异常,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出错,并且将传播异常..

于 2011-07-10T14:48:32.333 回答
0
  1. 粗略的方式(我认为),但应该适用于你的情况,是订阅

    AppDomain.CurrentDomain.UnhandledException

事件 riased,这将直接从函数中引发异常ExecFile(object o);

  1. 或者创建一个设置为 NEGATIVE 状态的状态机,以防 ExecFile(object o);方法中出现任何异常。

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

于 2011-07-10T15:08:41.963 回答