【发布时间】:2020-08-04 14:54:31
【问题描述】:
我正在编写一个基于 net core 3.1 linux 的 c# 控制台应用程序
预计会
- 异步运行作业
- 等待作业结束
- 捕捉终止信号并做一些干净的工作
这是我的演示代码:
namespace DeveloperHelper
{
public class Program
{
public static async Task Main(string[] args)
{
var http = new SimpleHttpServer();
var t = http.RunAsync();
Console.WriteLine("Now after http.RunAsync();");
AppDomain.CurrentDomain.UnhandledException += (s, e) => {
var ex = (Exception)e.ExceptionObject;
Console.WriteLine(ex.ToString());
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
};
AppDomain.CurrentDomain.ProcessExit += async (s, e) =>
{
Console.WriteLine("ProcessExit!");
await Task.Delay(new TimeSpan(0,0,1));
Console.WriteLine("ProcessExit! finished");
};
await Task.WhenAll(t);
}
}
public class SimpleHttpServer
{
private readonly HttpListener _httpListener;
public SimpleHttpServer()
{
_httpListener = new HttpListener();
_httpListener.Prefixes.Add("http://127.0.0.1:5100/");
}
public async Task RunAsync()
{
_httpListener.Start();
while (true)
{
Console.WriteLine("Now in while (true)");
var context = await _httpListener.GetContextAsync();
var response = context.Response;
const string rc = "{\"statusCode\":200, \"data\": true}";
var rbs = Encoding.UTF8.GetBytes(rc);
var st = response.OutputStream;
response.ContentType = "application/json";
response.StatusCode = 200;
await st.WriteAsync(rbs, 0, rbs.Length);
context.Response.Close();
}
}
}
}
希望它会打印
Now in while (true)
Now after http.RunAsync();
ProcessExit!
ProcessExit! finished
但它只输出
$ dotnet run
Now in while (true)
Now after http.RunAsync();
^C%
async/await 是否阻塞了 eventHandler 监视的 kill 信号?
意外异常事件处理程序也没有任何输出。
asp.net core 中有signal.signal(signal.SIGTERM, func) 吗?
【问题讨论】:
-
@Andy 谢谢,添加
Console.CancelKeyPress += (s,e) => {...}后, ctrl+c 将被Console.CancelKeyPress捕获,而kill 信号将被AppDomain.CurrentDomain.ProcessExit捕获。但是 AppDomain.CurrentDomain.ProcessExit 不等待,它只打印ProcessExit!,等待 task.delay() 之后的输出不打印 -
我有一个侧面问题。你为什么使用
HttpListener?您正在使用 .NET Core,为什么不使用 Kestrel 并获得一个运行得更好的完整 Web 服务器?以下是如何设置的示例:stackoverflow.com/a/48343672/1204153 -
我将整理一个示例,说明如何让所有内容优雅地退出。我有几个想法。
-
@Andy 使用 HttpListener 简单地打开一个端口并确认请求,通过这个简单的网络服务器实现,我可以向 consul 代理注册一个 HTTP 检查,谢谢你的建议,我会看看, kestrel impl 是否比 httplistener 简单(代码行数少于)?
标签: c# .net-core async-await