【发布时间】:2021-09-24 00:02:09
【问题描述】:
我的 .NET5 Web API 项目(除了 REST)监听 Telegram 消息。目标很简单:
- 当用户发送 exit 消息时 - 使用退出代码 8 终止应用
- 当消息处理程序抛出 SeriousException - 使用退出代码 8 终止应用程序
不幸的是,由于消息轮询的异步性质,我正在努力实现这一目标。我在 GitHub 中准备了一个示例项目:https://github.com/chris-rutkowski/AsExPoC。
我在 Stack Overflow 上发现了许多类似的主题,但没有什么真正适合我,而且大量建议的解决方案(一些 AsyncHelpers 等)似乎有点矫枉过正。我正在考虑将Thread.CurrentThread 传递给服务并以某种方式抛出异常,但我不知道如何,或者它是否可能发生,即使它是最佳实践。我对 C#+.NET 了解不多,但是在 Swift (iOS) 中,我会很容易地解决它,只需 3 行,包括大括号:
DispatchQueue.main.async {
throw ForcedExitException()
}
这是我精简的 .NET5 Web Api,您可以在 repo 中找到。
Program.cs
public class Program
{
public static int Main(string[] args)
{
try
{
var host = CreateHostBuilder(args).Build();
var service = host.Services.GetRequiredService<DummyService>();
service.Run();
// other services are running too - I cannot just wait for DummyService to throw the exception
host.Run();
return 0;
}
catch (ForcedExitException)
{
return 8;
}
catch (Exception ex)
{
return 1;
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
DummyService.cs
public class DummyService
{
private readonly DummyMessenger _dummyMessenger;
public DummyService()
{
_dummyMessenger = new DummyMessenger();
}
public async void Run()
{
_dummyMessenger.StartReceiving();
_dummyMessenger.Add(async (_, message) => {
Console.WriteLine($"received message {message}");
await Task.Delay(50);
if (message == "exit")
throw new ForcedExitException();
});
}
}
我的期望:
Exited with error code 8
这是我在控制台中看到的:
Exited with error code 134, with the following stacktrace
Unhandled exception. AsExPoC.ForcedExitException: Exception of type 'AsExPoC.ForcedExitException' was thrown.
at AsExPoC.DummyService.<>c.<Run>b__2_0(Object _, String message) in /Users/chris/Developer/Projects/AsExPoC/AsExPoC/DummyService.cs:line 36
at AsExPoC.DummyMessenger.StartReceiving() in /Users/chris/Developer/Projects/AsExPoC/AsExPoC/DummyMessenger.cs:line 27
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__140_1(Object state)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
感谢反馈。
【问题讨论】:
-
我没有考虑太多,但你试过
Environment.Exit(Int32) -
@TheGeneral 感谢您的关注。它不会改变任何东西。我在 GitHub 上创建了示例项目:github.com/chris-rutkowski/AsExPoC。同时,我将更新我的问题以使其更简单。
标签: c# .net asynchronous exception exit