2009-04-07 1 views
0

Я пытаюсь получить список вызовов, сделанных с начала блока try для исключения. В приведенном ниже коде, когда я попасть в блок улов, StackTrace в объекте Исключение составляют следующие:Как получить историю вызовов метода?

на ConsoleApplication.Program.MethodC()/в ConsoleApplication.Program.Main (String [] арг).

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

static void MethodA() { } 
static void MethodB() { } 
static void MethodC() { throw new Exception(); } 

static void Main(string[] args) 
{ 
    try 
    { 
     MethodA(); 
     MethodB(); 
     MethodC(); 
    } 
    catch (Exception e) 
    { 
     // Get list of calls 
     throw; 
    } 
} 

Я был удивлен, увидев, что свойство StackTrace объекта Exception не StackTrace объект. Есть ли причина для этого?

В конце концов, цель всего этого проста. Если во время выполнения кода возникает исключение, я хочу посмотреть метаданные (атрибут) каждого из вызванных методов.

ответ

1

Как я понимаю ваш вопрос, вы хотите знать, какие методы были вызваны до MethodC в вашем блоке try. Я не думаю, что вы можете это сделать без добавления кода в свои методы.

Когда MethodA заканчивает выполнение, он больше не находится в стеке, поэтому отсюда вы не можете получить информацию. То же самое касается метода MethodB, и только MethodC находится в стеке, когда происходит Исключение.

0

Кажется, вы не сможете получить трассировку стека для каждого метода, вызванного блоком try, если вы не добавите собственный код ведения журнала для каждого метода. Однако вы можете легко создать опцию System.Diagnostics.StackTrace из исключения, просто передав объект Exception в конструктор. Это позволит получить всю информацию о трассировке стека, включая то, было ли исключение выбрано из MethodA/MethodB/MethodC, которое может быть по крайней мере полезно для вас.

Пример кода:

static void MethodA() { } 
static void MethodB() { } 
static void MethodC() { throw new Exception(); } 

static void Main(string[] args) 
{ 
    try 
    { 
     MethodA(); 
     MethodB(); 
     MethodC(); 
    } 
    catch (Exception e) 
    { 
     System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace(e); 
     System.Diagnostics.StackFrame frame = null; 
     System.Reflection.MethodBase calledMethod = null; 
     System.Reflection.ParameterInfo[] passedParams = null; 
     for (int x = 0; x < callStack.FrameCount; x++) 
     { 
      callStack.GetFrame(x); 
      calledMethod = frame.GetMethod(); 
      passedParams = calledMethod.GetParameters(); 
      foreach (System.Reflection.ParameterInfo param in passedParams) 
       System.Console.WriteLine(param.ToString()); 
     } 
    } 
} 

(Вы можете увидеть this SO thread для оригинального ответа, содержащего код, я просто немного изменили его.).

Надежда, что, по крайней мере частичное решение вашего вопроса ,

+0

Код не работает. Он генерирует исключение NullRef в frame.GetMethod(). – Martin

+0

Это довольно странно ... Осмотрите другие свойства объекта StackFrame - это может быть просто потому, что исключение было выбрано непосредственно в блоке try. – Noldorin

0

Вы можете легко получить объект StackTrace из любого места вашего кода, но, как уже указывалось, вы не можете получить полную историю вызовов методов.