2015-07-12 159 views
1

我試圖在下面的示例中獲取大多數異常堆棧跟蹤的內部方法名稱。由於不明原因,我總是得到MoveNext方法名稱,而不是真名。我該如何解決它?在TPL數據流塊中拋出的異常方法名始終是MoveNext()

var st = new StackTrace(ex, true); 
var frame = st.GetFrames()?.First(y => y.GetFileName() != null); 
var method = frame.GetMethod().ToString(); // result: Void MoveNext() 
var method2 = frame.Name; // result: MoveNext 

UPDATE:

這時候,異常的TPL Dataflow塊的委託拋出發生:

private async Task Parse(ListItem item) 
{ 
    await Task.Delay(1); 
    throw new Exception("Error"); 
} 

// ...

var parseBlock = new ActionBlock<ListItem>(
        async x => { await Parse(x).ConfigureAwait(false); }); 

我得到MoveNext從與任何代表任何塊。 Stacktrace:

at RP.Core.ListsPipeline.<Parse>d__21.MoveNext() in Class.cs:line 179 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() 
at Class.<<Start>b__18_0>d.MoveNext() in Class.cs:line 81 

我想要得到Parse方法名稱(StackTrace的第一個字符串)。

+0

向我們展示觸發異常的代碼。 –

+0

發佈的代碼是「如何獲得例外信息」,是不必要的。 –

+0

同時發佈確切的異常細節(從調試器窗口)。 –

回答

3

此:

private async Task Parse(ListItem item) 
{ 
    await Task.Delay(1); 
    throw new Exception("Error"); 
} 

被翻譯成這樣:

private Task Parse() 
{ 
    Program.<Parse>d__0 <Parse>d__; 
    <Parse>d__.<>t__builder = AsyncTaskMethodBuilder.Create(); 
    <Parse>d__.<>1__state = -1; 
    AsyncTaskMethodBuilder <>t__builder = <Parse>d__.<>t__builder; 
    <>t__builder.Start<Program.<Parse>d__0>(ref <Parse>d__); 
    return <Parse>d__.<>t__builder.Task; 
} 

和你的方法的實際調用是狀態機的編譯器創建MoveNext()方法內。這實際上意味着代碼不在Parse()內部調用。這就是爲什麼你看到MoveNext作爲方法名稱,這就是爲什麼你將不能得到Parse作爲方法名稱。