【问题标题】:Process exit code is zero when server running服务器运行时进程退出代码为零
【发布时间】:2021-10-18 15:23:27
【问题描述】:

我有一个测试套件,其 Main 函数返回 1。但是,应用程序终止后的退出代码为 0。

这似乎与我在后台运行的 ASP.NET 服务器有关。如果我禁用服务器,退出代码如预期的那样为 1。

此代码按预期工作,控制台报告退出代码 1(这是 F# 语法,但我很确定这不相关):

[<EntryPoint>
let main (arts : string array) : int =
  1

虽然它的退出代码为 0,但这不是我所期望的:

[<EntryPoint>
let main (arts : string array) : int =
  MyHttpServer.init()
  1

这是 MyHttpServer.init 函数:

let init() : Task =
  Host
     .CreateDefaultBuilder()
     .Build()
     .RunAsync()

我的问题:让服务器在后台运行导致退出代码为零的原因是什么? .NET 中是否存在退出代码受后台任务和线程影响的地方?

注意:.NET 6 preview 5,但这发生在我从 .NET 5 开始使用的所有版本上。

【问题讨论】:

  • 如果您可以选择,使用退出代码通常不是一个好主意。进程中代码的任何部分都可以调用Environment.Exit,或者设置代码(c#)或ExitProcess(winapi),%ERRORLEVEL% env变量,例如:github.com/dotnet/aspnetcore/blob/main/src/Hosting/Hosting/src/…。您可以做的是使用调试器并在 ExitProcess 上放置一个断点。

标签: asp.net .net asp.net-core .net-core


【解决方案1】:

不太熟悉 F# 语法,但我怀疑如果 Init() 因错误/异常退出 b/c,则执行将永远不会到达返回 1 的行,因此会以 0 的值退出。

编辑: 如果调用Init时抛出异常,或者在Init可以返回之前抛出异常,未处理的异常会终止进程,返回1的代码不会被执行。

【讨论】:

  • Init 返回一个任务,但该任务从未被查看过。所以main 应该在任务完成之前完成
  • 是的,但是您假设对 init 的调用可以成功进行(例如,MyHttpServer 不为 null)并且 init 在返回之前不会引发异常。如果我没记错的话,未处理的异常会终止进程,因此会阻止它到达可以返回 1 的点。
  • 我知道init 在成功返回Task 之前不会抛出异常。你是说main 函数在清理(Disposes?)Task 之后才真正“返回”,这会在稍后引发异常?
  • 如果你已经通过调试器并知道Init 不会抛出异常并成功返回Task,那么这个讨论可能没有实际意义。我的意思是,例如,如果MyHttpServer 为空,则Init 调用将永远不会发生,并且将抛出空引用异常,从而导致进程终止。同样,如果Init 内部的代码在返回Task 之前抛出异常,则进程将终止。我无法确定是否会调用Dispose(我怀疑它会),无论如何,永远不会到达返回 1 的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多