2012-09-04 21 views
0

我正在處理Windows窗體主入口點中的頂級異常。我想訪問在我的處理程序中導致異常的調用方法/程序集。我有一種感覺,我將不得不使用痕跡,但我不知道在哪裏。獲取調用方法導致catch中的異常

Module Program 
    Sub Main() 
    Try 
     AddHandler AppDomain.CurrentDomain.UnhandledException, Function(sender, e) ExceptionHandler.Handle(sender, DirectCast(e.ExceptionObject, Exception)) 
     AddHandler Application.ThreadException, Function(sender, e) ExceptionHandler.Handle(sender, e.Exception) 
     Application.Run(ApplicationBase) 
    Catch ex As Exception 
     MessageBox.Show("Handled Exception") 
    End Try 
    End Sub 
End Module 

Public Class ApplicationBase 
    Public Sub MethodA() 
    'Causes an exception 
    File.ReadAllLines("") 
    End Sub 
End Class 

Public Class ExceptionHandler 

    Public Shared Function Handle(sender As Object, e As Exception) 
    Dim t As Type = sender.GetType() 
    'Retrieve the calling method here? 
    Dim callingMethod = "MethodA" 
    Return True 
    End Function 

End Class 

未來通過作爲發送者的目的是一種螺紋,我試圖看到,如果這將是該調用導致了異常的組件/對象類型。

我的問題是如何獲取方法名稱/信息,並在「handle」方法中推送對象名稱/程序集,如果可能的話?

編輯:

雖然e.ToString()將提出方法的名字 - 我期待訪問一個MethodInfo的列表/程序集/類型到異常是一樣的反射造成的,然後我可以得到.DLL等的版本號 - 我可能在這裏做夢,但是我想知道它是否可能?

編輯2:

我試圖e.TargetSite這爲methodA()異常返回File.ReadAllLines()我正在尋找這將導致異常的類方法的方法信息,因此該方法的信息會方法A - 雖然這比我想象的要接近得多。

回答

1

e.ToString()將返回包括堆棧跟蹤的完整詳細信息。堆棧跟蹤包含所有方法名稱。

+0

哇這一直漫長的一天不知道爲什麼我沒有意識到這一點。但是,這只是一般的異常字符串,我想要methodinfo或單個方法的名稱。反正我有把類型作爲對象或調用程序集,然後我可以用反射/ – LukeHennerley

+0

操縱我相信,e.TargetSite會爲你找到你正在尋找的東西。 –

+0

+1使我意識到 - 但我想要的一個小例子是在處理程序中有一個MethodInfo變量(Dim info爲MethodInfo),然後將其設置爲導致異常(MethodA)的Method。然後,如果可能的話,組件/類型。 – LukeHennerley

2

如果您想知道哪種方法拋出異常,可以使用Exception.TargetSite屬性;它返回一個MethodBase

如果拋出此異常的方法不可用並且堆棧跟蹤不是空引用(Visual Basic中爲Nothing),則TargetSite將從堆棧跟蹤中獲取該方法。如果堆棧跟蹤是空引用,則TargetSite也會返回空引用。

如果您想要在異常時查找堆棧跟蹤,以便在您的代碼中查找方法(而不是庫代碼中的方法),則必須自行分析堆棧跟蹤。

你可以得到一個異常的堆棧跟蹤:

Dim stackFrame = stackTrace.GetFrame(index) 

你可以從堆棧幀信息:

Dim stackTrace = new StackTrace(ex) 

您可以通過索引得到一個單一的堆棧幀

Dim method = stackFrame.GetMethod() 

然後,你必須想出一個算法,從上到下展示棧跟蹤ng滿足您想要報告的堆棧幀的條件的第一幀。這是一個非常簡單的算法,它可以找到執行程序集中的第一幀。

Dim stackTrace = new StackTrace(ex) 
Dim i As Integer 
For i = 0 To stackTrace.FrameCount - 1 
    Dim stackFrame = stackTrace.GetFrame(i) 
    Dim method = stackFrame.GetMethod() 
    If (method.DeclaringType.Assembly = Assembly.GetExecutingAssembly()) Then 
    ' Found the method - do something and exit the loop 
    Exit For 
    End If 
Next i 
+1

如果將stackFrame的聲明更改爲Dim stackFrame As System.Diagnostics.Stackframe,則可以獲取stackFrame.GetFileLineNumber(),但這可能會返回0。 – Martin

相關問題