My .NET5 Web API project (in addition to REST) listens to Telegram messages. The goals are simple:
- when a user sends exit message - terminate the app with exit code 8
- when a message handler throws a SeriousException - terminate the app with exit code 8
Unfortunately, due to the asynchronous nature of message polling, I'm struggling to achieve this goal. I've prepared a sample project in GitHub: https://github.com/chris-rutkowski/AsExPoC .
I found many similar subjects on Stack Overflow but nothing really works for me, moreover the plenty of suggested solutions (some AsyncHelpers etc) seems like overkill. I was thinking about passing Thread.CurrentThread to the service and somehow throw the exception on it, but I don't know how, or if it's event possible and even if it is, is it is a best practice. I don't have that much knowledge in C#+.NET, but In Swift (iOS), I would solve it so easily, just 3 lines including curly brackets:
DispatchQueue.main.async {
throw ForcedExitException()
}
This is my stripped down .NET5 Web Api, you can find in the 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();
});
}
}
What I expect:
Exited with error code 8
This is what I see in the Console:
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()
Appreciate feedback.
Environment.Exit(Int32)