"Profile with async awareness" causes infinite loop
AndreasH
Posts: 2
Hello!
We have a problem when profiling our application.
It is pretty tricky but I will try my best to explain.
Our application works just fine. Also, profiling the application with "Profile with async awareness" turned off works fine.
When "Profile with async awareness" is turned on, the same async method is repeated over and over again indefinitely.
Simplified it looks like that:
The first invocation of StandardExecutionJob.ExecutionBody has the following stack trace:
From the second invocation on (for ever) it looks like:
It seems like the task continuation points back to the beginning of the first method instead of resuming it... or something.
Any idea?
Regards,
Andreas
We have a problem when profiling our application.
It is pretty tricky but I will try my best to explain.
Our application works just fine. Also, profiling the application with "Profile with async awareness" turned off works fine.
When "Profile with async awareness" is turned on, the same async method is repeated over and over again indefinitely.
Simplified it looks like that:
internal sealed class StandardExecutionJob<TService, TArgs, TResult> : ExecutionJobBase<TResult> { // ... protected async override Task<TResult> ExecutionBody() { // FINE // ## Stack traces from here ## var result = await adapter.ExecuteAsync(service, args); // !!!! NEVER HERE!!!! return result; } // ... } internal abstract class FuncExecutionAdapterBase<TService, TArgs, TResult> : IFuncExecutionAdapter<TService, TArgs, TResult> { // ... /// <inheritdoc /> public async Task<TResult> ExecuteAsync(TService service, TArgs arguments) { try { // FINE var result = await ExecutionBody(service, arguments); // FINE return result; } catch (UserException e) { // ... } catch (RuntimeUserException e) { // ... } } // ... protected abstract Task<TResult> ExecutionBody(TService service, TArgs arguments); }
- StandardExecutionJob.ExecutionBody is called
- FuncExecutionAdapterBase.ExecuteAsync is called
- FuncExecutionAdapterBase.ExecuteAsync returns a value
- Execution never returns to StandardExecutionJob.ExecutionBody
- Instead StandardExecutionJob.ExecutionBody is invoked anew, again and again and again...
The first invocation of StandardExecutionJob.ExecutionBody has the following stack trace:
Execution.Jobs.StandardExecutionJob`3 [(null)] - at Execution.Jobs.StandardExecutionJob`3.<ExecutionBody>d__0.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Execution.Jobs.StandardExecutionJob`3.ExecutionBody()
at Execution.Jobs.ExecutionJobBase`1.<Execute>d__0.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Execution.Jobs.ExecutionJobBase`1.Execute()
at Execution.Processors.ExecutionJobProcessor.<ProcessExecutionJob>d__5.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Execution.Processors.ExecutionJobProcessor.ProcessExecutionJob(IExecutionJob job)
at Execution.Processors.ExecutionJobProcessor.<.ctor>b__2(IExecutionJob t)
at System.Threading.Tasks.Dataflow.ActionBlock`1.ProcessMessageWithTask(Func`2 action, KeyValuePair`2 messageWithId)
at System.Threading.Tasks.Dataflow.ActionBlock`1.<>c__DisplayClass7.<.ctor>b__1(KeyValuePair`2 messageWithId)
at System.Threading.Tasks.Dataflow.Internal.TargetCore`1.ProcessMessagesLoopCore()
at System.Threading.Tasks.Task.Execute()
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.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
From the second invocation on (for ever) it looks like:
Execution.Jobs.StandardExecutionJob`3 [(null)] - at Execution.Jobs.StandardExecutionJob`3.<ExecutionBody>d__0.MoveNext()
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.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining, Task& currentTask)
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetResult(TResult result)
at Execution.Adapters.FuncExecutionAdapterBase`3.<ExecuteAsync>d__0.MoveNext()
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.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining, Task& currentTask)
at System.Threading.Tasks.Task.FinishContinuations()
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.ThreadPoolWorkQueue.Dispatch()
It seems like the task continuation points back to the beginning of the first method instead of resuming it... or something.
Any idea?
Regards,
Andreas
Comments
I'm sorry that you've hit this issue. This is a known problem, the reference is PP-3843. Unfortunately I don't have an eta on the fix, but I will update you as soon as I know more.
A beta release is available that should address the problem you've had, it can be found here: https://www.simple-talk.com/blogs/2016/ ... i=25469732.
Please let me know if you have any further issues.