Использование try-catch между несколькими процедурами - PullRequest
0 голосов
/ 10 июля 2011

Это что-то вроде продолжения предыдущего вопроса, который я задал, хотя теперь я могу предоставить гораздо больше кода, чтобы улучшить свой вопрос и дополнительно показать мою проблему с этой областью.

У меня естьтри процедуры здесь.Две из этих подпрограмм работают вместе - и в случае успеха загрузят сборку в память с помощью 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);


}

Я могу уточнить больше, если необходимо, но я не уверен, какую другую информацию включить в данный момент.

Ответы [ 5 ]

1 голос
/ 10 июля 2011

Используйте оператор throw в операторе catch ExecFile, чтобы вызвать то же «исключение» (или ошибку), полученное в ExecFile. Например:

 catch {
      throw;
 }

Думаю, я понял проблему. ExecFile (byte []) запускает поток и немедленно возвращается, не дожидаясь выхода потока. Чтобы этот метод мог ожидать завершения потока, добавьте:

 T.Join();

сразу после запуска потока. (Однако во избежание двусмысленности следует переименовать ExecFile (объект). Я также не уверен, будет ли ExecFile (byte []) перехватывать исключение из ExecFile (объект).)

0 голосов
/ 10 июля 2011
  1. Грубый путь (я думаю), но должен работать в вашем случае, это подписаться на

    AppDomain.CurrentDomain.UnhandledException

событие сгенерировано, что вызовет исключение, вызванное непосредственно из функции ExecFile(object o);

  1. Или создайте конечный автомат, который установлен в НЕГАТИВНОЕ состояние в случае любого исключения в методе ExecFile(object o);.

  2. Или просто не делайте это в многопоточности:)

0 голосов
/ 10 июля 2011

Просто посмотрите в стеке вызовов, какой метод снова вызывает метод ExecuteDataIntoMemory?

если вы используете Visual Studio IDE, установите точку останова в окне сообщения:

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

, затем просто перейдите кпросмотреть меню, оттуда найти окно стека вызовов, которое нужно отобразить, и посмотреть на стек вызовов (показать внешний код в стек вызовов)

возможно, это может помочь.

0 голосов
/ 10 июля 2011

Если я вас хорошо понимаю, вы хотите, чтобы 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- В блоке catch метода ExecFile (byte [] data) повторно сгенерировать исключение, чтобы его можно было обработать из метода вызывающего объекта два, т. Е.

try
{
    ExecFile((object)data);
}
catch
{
    MessageBox.Show("caught some error ...");
    throw;
}
0 голосов
/ 10 июля 2011

Если вы поймаете исключение в 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 ошибок в этом методе, и исключение будет распространяться ..

...