问题
Is it possible to get an equivalent stack trace that is provided by the visual studio 2019 debugger.
Eg if I breakpoint in my async code inside of visual studio I see the following stack trace within the "Call Stack" window
company.Common.dll!company.Common.Api.ResourcesDatabase.Lock() Line 58 C#
company.Common.dll!company.Common.Api.ResourcesDatabase.ResourcesDatabase(bool openAndCreateDB) Line 29 C#
company.Api.dll!company.Api.GlobalsDownloader.DownloadNewGlobals_UnderLock(System.Func<company.Common.Api.DTO.GlobalsType, System.Threading.Tasks.Task> reloadGlobals, company.Common.Api.DTO.GlobalsType globalsType) Line 124 C#
[Resuming Async Method]
[External Code]
[Async Call Stack]
[Async] company.Api.dll!company.Api.ApiService.VerifyLogin_UnderLock(bool skipInitTasks, System.Threading.CancellationToken ct) Line 1147 C#
[Async] company.Api.dll!company.Api.ApiService.VerifyLogin(System.Threading.CancellationToken ct) Line 955 C#
[Async] company.Api.dll!company.Api.ApiService.Init(System.Action initComplete, bool dontCheckForUpdates) Line 250 C#
[Async] company.Editor.exe!company.Editor.ViewModel.MainViewModel.Init() Line 524 C#
[Async] company.Editor.exe!company.Editor.ViewModel.MainViewModel.InitViewModel.AnonymousMethod__31_0() Line 331 C#
If I call new System.Diagnostics.StackTrace(1,true)
I get the following
at company.Common.Api.ResourcesDatabase.Lock()
at company.Common.Api.ResourcesDatabase..ctor(Boolean openAndCreateDB)
at company.Api.GlobalsDownloader.<DownloadNewGlobals_UnderLock>d__6.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext(Object stateMachine)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass4_0.<OutputAsyncCausalityEvents>b__0()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke()
at System.Runtime.CompilerServices.TaskAwaiter.<>c__DisplayClass11_0.<OutputWaitEtwEvents>b__0()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining, Task& currentTask)
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task.FinishStageThree()
... 3 more layers of async
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task.FinishStageThree()
at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.CompleteFromAsyncResult(IAsyncResult asyncResult)
at System.IO.Compression.DeflateStreamAsyncResult.Complete(Object result)
at System.IO.Compression.DeflateStream.ReadCallback(IAsyncResult baseStreamResult)
at System.IO.Stream.ReadWriteTask.InvokeAsyncCallback(Object completedTask)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.IO.Stream.ReadWriteTask.System.Threading.Tasks.ITaskCompletionAction.Invoke(Task completingTask)
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task.FinishStageThree()
at System.Threading.Tasks.Task.FinishStageTwo()
at System.Threading.Tasks.Task.Finish(Boolean bUserDelegateExecuted)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() 6.67s
The bit that I really like about the visual studio debugger is it can figure out what occurs before the async state engine.
[Resuming Async Method]
[External Code]
[Async Call Stack]
Eg the code before the "Async Call Stack". How does the visual studio debugger get this call stack and how can I get this in code?
I have tried the following nuget package which cleans up the stack slightly but doesn't help find the jump before the native code transition.
https://github.com/benaadams/Ben.Demystifier
来源:https://stackoverflow.com/questions/58620205/get-stack-trace-of-c-sharp-async-calls-using-the-api-that-the-visual-studio-debu