简体   繁体   中英

asp.net core self hosted app leaks on webhost respawn

I have a self-hosted asp.net core app that needs to occassionally respawn its WebHost with a new context. App registers a shared resource as a singleton in asp.net DI container.

            services.AddSingleton<MyDep>();

Controller depends on a share resource:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    public MyDep Dep { get; }

    public ValuesController(MyDep dep)
    {
        Dep = dep;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] {
            new string(Dep.Content),
            "value2" };
    }
 }

It leaks the resources bound to the previous instance. I reproduced the problem using a demo app (slightly modified asp.net core api project template).

public static void Main(string[] args)
    {
        var p = new Program();
        while (true)
        {
            p.Boot(args);
            GC.Collect(2, GCCollectionMode.Forced, true);
        }
    }

    private void Boot(string[] args)
    {
        webHost = CreateWebHostBuilder(args).Build();
        webHost.RunAsync();
        Thread.Sleep(5000);
        webHost.StopAsync().Wait();
        webHost.Dispose();
    }

I am seeing n instances of controller where n is number of http requests to the controller - controller is not being disposed at all. Profiler indicates a long path to root with System.Threading.OverlappedData at the end of the chain. Could you suggest what is wrong with this setup? sample app

path to root

I am seeing n instances of controller where n is number of http requests to the controller

That's the expected behavior. Controllers are created for each request by default.

From your snapshot I don't see there are multiple MyDep instances. The snapshot shows the instances of Func<ValueController, MyDep> , which is not a singleton as expected. If you invoke the delegate, you will get the same instance of MyDep among different requests. Generally speaking, there is nothing wrong here. You are tracing the wrong type.

Okay, I've shown the wrong trace for the problem described. The context was not properly released nevertheless.

I found a solution: IApplicationLifecycle.StopApplication as described here -> https://www.blakepell.com/asp-net-core-ability-to-restart-your-site-programatically-updated-for-2-0

The context is being released properly and memory footprint is not growing infinitely anymore

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM