Mis*_*tyK 21 .net c# asp.net-web-api
我正在使用Process类在ASP.NET Core(.NET Framework)中生成子进程:
var process = new Process
{
StartInfo = new ProcessStartInfo(executableDir)
{
Arguments = commandDefinition.CommandDef.ArgumentsAsString,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = _contentPath,
},
};
process.Start()
Run Code Online (Sandbox Code Playgroud)
据我所知,当父(ASP.Net Core)进程被杀死时,子进程应该保持活跃状态.我使用两个控制台应用程序测试了这种行为,并且在杀死父进程后,子进程永远不会被杀死 但是,当我在ASP.NET Core中生成一个新进程时,子进程在以下情况下被杀死:
如果通过任务管理器杀死父级,它不会被杀死.(经过一些测试后并非总是如此)
从上面我怀疑ASP.NET Core中有一种机制可以在成功退出时杀死所有子进程.它在某处记录了吗?有没有办法避免它?我找不到有关此类行为的任何信息.
编辑:repro实际上非常简单.
Startup班级 var process = new Process
{
StartInfo = new ProcessStartInfo("calc.exe")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
},
};
process.Start();
Run Code Online (Sandbox Code Playgroud)
Edit2:问题似乎在IIS中.我在launchSettings.json中有两个配置文件.如果我使用IISExpress运行它然后它会关闭,但是当使用第二个时它会存在.
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApplication3Core": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:52135/"
}
Run Code Online (Sandbox Code Playgroud)
Edit4:
我用过程监视器做了一些研究,这是输出:
正如您在ss1中所看到的,iisexpress存在"Process Exit"操作,然后有许多不可用的日志,并且在一段时间后有一个针对calc.exe的Process Exit.它与正常退出没有任何不同.唯一的区别是后面的日志说"CloseFile"和我的网络应用程序的路径,我不知道它实际意味着什么.肯定是iis杀死了calc.exe.我有IIS Express 10.0.14358版本(服务器版本,我发现这也是10)
正如我在评论中所说,有一个由 ASP.NET 核心在进程外场景中创建的作业对象。相关的源代码部分在这里:
HRESULT
SERVER_PROCESS::SetupJobObject(VOID)
{
HRESULT hr = S_OK;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { 0 };
if (m_hJobObject == NULL)
{
....
jobInfo.BasicLimitInformation.LimitFlags =
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (!SetInformationJobObject(m_hJobObject,
JobObjectExtendedLimitInformation,
&jobInfo,
sizeof jobInfo))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
}
return hr;
}
Run Code Online (Sandbox Code Playgroud)
根据文档,JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE:
当作业的最后一个句柄关闭时,导致与作业关联的所有进程终止。
如果进一步挖掘来源,它似乎不是可选的。
现在,如果您重现您的步骤,您实际上可以自己看到这一点。使用Process Explorer并导航到您的 dotnet.exe 进程,它将显示以下内容:
calc.exe保持活动状态(至少在我的 Windows 10 安装中,因为它现在是一个 WinRT 应用程序,因此它最终不会成为 dotnet.exe 的子项),这就是我使用的原因notepad.exeiisexpress.exe也创建了一个作业对象,但它被配置为脱离正常,这意味着它不会杀死子进程。VSIISExeLauncher.exe之间的中间过程。这个还创建了一个带有“关闭时杀死”的作业对象以增加混乱......iisexpress.exedotnet.exe| 归档时间: |
|
| 查看次数: |
1062 次 |
| 最近记录: |