Как получить точный номер строки трассировки стека в обработке исключений - PullRequest
1 голос
/ 14 января 2020

Я пытаюсь понять обработку исключений в C#. У меня есть пример программы.

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();

        try
        {
            p.Method2();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Enter into Main()");
            Console.WriteLine("The original Stack Trace Line No 47 is missing in current Stack Trace.");
            Console.WriteLine("------------------------------------------------------------------------");
            Console.Write(ex.StackTrace.ToString());
            Console.ReadKey();
        }
    }

    private void Method2()
    {
        try
        {
            Method1();
        }
        catch (Exception ex)
        {
            //throw ex resets the stack trace Coming from Method 1 and propogates it to the caller(Main)
            throw;
        }
    }

    private void Method1()
    {
        try
        {
            throw new Exception("Inside Method1");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception " + ex);
            throw;
        }
    }
}

Я хотел бы видеть исходный номер строки трассировки стека в основном методе (который я вижу в блоке catch метода Method1). Возможно ли это?

enter image description here

Ответы [ 2 ]

0 голосов
/ 14 января 2020

Я нахожусь. NET Core, но я думаю, что он работает так же для. NET Framework. Я скопировал ваш код и просто добавил номер строки в качестве комментария в интересные строки:

private void Method1()
{
    try
    {
        throw new Exception("Inside Method1"); // line 42
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception " + ex);
        throw; // line 47
    }
}

Приведенный выше код выдает следующее:

в Main.Program.Method1 () в C: ... \ Main.cs: строка 42

в обоих Console.WriteLine в Method1 и Main.

Если заменить throw на throw ex в блоке перехвата он печатает:

в Main.Program.Method1 () в C: ... \ Main.cs: строка 42

в Console.WriteLine в Method1 и

в Main.Program.Method1 () в C: ... \ Main.cs: строка 47

in Console.WriteLine в Main, потому что исключение переброшено, поэтому номер строки меняется.

Все это говорит о том, что ваш код работает так, как вы ожидаете; поэтому код, который вы выполняете, может быть не тот, который вы компилируете: -)

0 голосов
/ 14 января 2020

Вы можете использовать класс StackTrace для получения дополнительной информации, такой как ClassName, LineNumber et c. Например, ниже

catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

Изменить

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

public static AdditionalInformation GetStackTrace(Exception exception)
        {
            var trace = new StackTrace(exception, true);
            var reflectedType = trace.GetFrame(0).GetMethod().ReflectedType;
            var additionalInformation = new AdditionalInformation();
            if (reflectedType != null)
            {
                additionalInformation = new AdditionalInformation()
                {
                    Column = trace.GetFrame(0).GetFileColumnNumber(),
                    Line = trace.GetFrame(0).GetFileLineNumber(),
                    MethodName = reflectedType.FullName,
                    File = trace.GetFrame(0).GetFileName()
                };

            }
            return additionalInformation;
        }
...