Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Causality is lost when Task.Run is used #528

Closed
davidfowl opened this issue Oct 5, 2019 · 2 comments · Fixed by #2964
Closed

Causality is lost when Task.Run is used #528

davidfowl opened this issue Oct 5, 2019 · 2 comments · Fixed by #2964
Assignees
Labels
dotnet-dump enhancement New feature or request
Milestone

Comments

@davidfowl
Copy link
Member

Causality is lost when Task.Run is used. This makes sense but I wonder if it's possible to stitch the async stacks in this case. Here's the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebApplication352
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await Task.Run(async () =>
                    {
                        await Task.Delay(10000);

                        await context.Response.WriteAsync("Hello World!");
                    });
                });
            });
        }
    }
}

This is what dumpasync -stacks looks like:

0000021214e64c18 00007ff8325691c0       96          0 WebApplication352.Startup+<>c__DisplayClass1_0+<<Configure>b__2>d
Async "stack":
.0000021114e82640 System.Threading.Tasks.UnwrapPromise`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib]]
--------------------------------------------------------------------------------

0000021114e82688 00007ff832568770       96          0 WebApplication352.Startup+<>c+<<Configure>b__1_1>d
Async "stack":
.0000021114e82728 (0) Microsoft.AspNetCore.Routing.EndpointMiddleware+<<Invoke>g__AwaitRequestTask|6_0>d
..0000021114e827b0 (0) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9
...0000021114e82840 (1) Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests>d__217`1[[System.__Canon, System.Private.CoreLib]]  
....0000021114e82900 (0) Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequestsAsync>d__216`1[[System.__Canon, System.Private.CoreLib]]

cc @stephentoub

@davidfowl davidfowl changed the title Causality is lost when Task.Run is used Causality is lost when Task.Run is used Oct 5, 2019
@davidfowl
Copy link
Member Author

Simpler example:

async Task StateMachine1()
{
    await Task.Run(StateMachine2);
}

async Task StateMachine2()
{
    await Task.Delay(5000);
}
0000016a796d1890 00007ff82fa127b8       96          0 WebApplication352.Program+<StateMachine2>d__3
Async "stack":
.0000016bf9725180 System.Threading.Tasks.UnwrapPromise`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib]]
--------------------------------------------------------------------------------
0000016bf9725288 00007ff82f9feda8       96          0 WebApplication352.Program+<StateMachine1>d__2
--------------------------------------------------------------------------------

@sywhang sywhang added dotnet-dump enhancement New feature or request labels Oct 5, 2019
@mikem8361 mikem8361 added this to the 3.1 milestone Oct 7, 2019
@noahfalk noahfalk modified the milestones: 3.1, 5.0 Oct 8, 2019
@tommcdon tommcdon modified the milestones: 5.0, 6.0 Dec 18, 2020
@tommcdon tommcdon modified the milestones: 6.0.0, 7.0.0 Jun 21, 2021
@stephentoub
Copy link
Member

I've rewritten dumpasync in C# and I've addressed this as well (or at least the simpler repro successfully connects the stacks... I didn't try the original).

@ghost ghost closed this as completed in #2964 Apr 14, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jun 27, 2023
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dotnet-dump enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants