我有一个使用.NET 4.0的C#控制台应用程序项目,安装了Microsoft.Bcl.Async软件包.我用这个代码:
internal class Program
{
private static void Main(string[] args)
{
Foo().Wait();
}
static void Log(Exception ex)
{
}
private static async Task Foo()
{
try
{
await DoSomething();
}
catch (Exception ex)
{
Log(ex);
}
}
private static async Task DoSomething()
{
throw new DivideByZeroException();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在Log方法中放置一个断点,我得到了DivideByZero异常,但我看到的堆栈跟踪是:
at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.Runtime.CompilerServices.TaskAwaiter.GetResult()
at AsyncStacks.Program.<Foo>d__0.MoveNext() in p:\Sandbox\AsyncStacks\AsyncStacks\Program.cs:line 25
Run Code Online (Sandbox Code Playgroud)
这个堆栈跟踪几乎没用,因为它没有告诉我实际抛出异常的位置.
如果我将项目更改为目标.NET 4.5,我会得到一个更有用的异常:
at AsyncStacks.Program.<DoSomething>d__3.MoveNext() in p:\Sandbox\AsyncStacks\AsyncStacks\Program.cs:line 35
--- End of stack trace from …Run Code Online (Sandbox Code Playgroud) c# asynchronous exception-handling task-parallel-library async-await
使用log4net声明为:
private readonly ILog log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType());
Run Code Online (Sandbox Code Playgroud)
在异步方法或任务中,如下所示:
public async void CheckSomething()
{
log.Info(null);
//....
}
Run Code Online (Sandbox Code Playgroud)
日志MoveNext而不是CheckSomething.知道如何让它记录一个实际的方法名称?
由于.NET 4.5之前的运行时(包括SL/WP)不是异步感知的,因此它们生成的堆栈跟踪显示编译器生成的类/方法名称(如d_15).
有没有人知道在给定运行时堆栈跟踪,程序集和pdb的情况下生成更好的堆栈跟踪的实用程序?
要明确:我不是在寻找一个完整的异步堆栈,只是更好地了解实际抛出异常的方法
看来上面的陈述不够清楚,所以这里有一个例子:
public async void Foo()
{
await Bar();
}
public async Task Bar()
{
async SomethingToMakeThisMethodAsync();
throw new Exception()
}
Run Code Online (Sandbox Code Playgroud)
抛出异常时Bar,stacktrace将只包含生成的方法名称(d_15()).我不在乎Foo叫Bar.我只是想知道Bar是抛出异常的方法
debugging exception-handling stack-trace visual-studio async-await
我在ASP.NET Web应用程序中使用以下方法来接收异常的堆栈跟踪:
public static void getStackTraceInfo(System.Diagnostics.StackTrace trace)
{
for (int i = 0; i < trace.FrameCount; i++)
{
int nLine = trace.GetFrame(i).GetFileLineNumber();
int nCol = trace.GetFrame(i).GetFileColumnNumber();
string methodName = trace.GetFrame(i).GetMethod().Name;
}
}
try
{
}
catch(Exception ex)
{
getStackTraceInfo(new System.Diagnostics.StackTrace(ex, true));
}
Run Code Online (Sandbox Code Playgroud)
如果我在Visual Studio 2010开发环境中运行它,它会为我提供完整的行/列/方法名称信息,但在IIS上的生产环境中,它将返回所有0和方法名称为空字符串.
我是否还需要做一些特殊的事情才能使它在IIS上运行?
async-await ×3
c# ×3
debugging ×2
stack-trace ×2
asp.net ×1
asynchronous ×1
log4net ×1
methodbase ×1