我有一个自托管的asp.net核心应用,需要偶尔使用新的上下文重新生成其WebHost。 App在asp.net DI容器中将共享资源注册为单例。
services.AddSingleton<MyDep>();
控制器取决于共享资源:
[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" };
}
}
它泄漏绑定到前一个实例的资源。我使用演示应用程序(稍微修改了asp.net核心api项目模板)重现了该问题。
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();
}
我看到了n个控制器实例,其中n是对控制器的http请求数-控制器根本没有被处置。 事件探查器在链的末尾使用System.Threading.OverlappedData指示到root的长路径。您能否建议此设置有什么问题? sample app
答案 0 :(得分:1)
我看到了n个控制器实例,其中n是对控制器的http请求数
这是预期的行为。默认情况下,将为每个请求创建控制器。
在your snapshot中,我看不到有多个MyDep
实例。快照显示了Func<ValueController, MyDep>
的实例,该实例不是预期的单例。如果调用委托,您将在不同请求中获得MyDep
的相同实例。一般来说,这里没有错。您正在寻找错误的类型。
答案 1 :(得分:0)
好的,我为所描述的问题显示了错误的踪迹。但是,上下文尚未正确释放。
我找到了一个解决方案:IApplicationLifecycle.StopApplication,如此处所述-> https://www.blakepell.com/asp-net-core-ability-to-restart-your-site-programatically-updated-for-2-0
上下文已正确释放,内存占用也不再无限增长