停止自托管owin服务器时完成当前请求

我有OWIN服务器作为控制台应用程序的一部分。 你可以在这里看到主要方法:

class Program { public static ManualResetEventSlim StopSwitch = new ManualResetEventSlim(); static void Main(string[] args) { Console.CancelKeyPress += (s, a) => { a.Cancel = true; StopSwitch.Set(); }; using (WebApp.Start("http://+:8080/")) { Console.WriteLine("Server is running..."); Console.WriteLine("Press CTRL+C to stop it."); StopSwitch.Wait(); Console.WriteLine("Server is stopping..."); } Console.ReadKey(); Console.WriteLine("Server stopped. Press any key to close app..."); } } 

当请求的处理稍微长一点并且同时用户按下CTRL + C以停止应用程序时,立即停止请求处理并且不发送响应。 是否有可能改变这种行为? 我想拒绝所有新请求,但要等到当前正在处理的请求完成并在此之后停止服务器。

我最初的想法是创建OWIN中间件,它将跟踪当前正在处理的请求并推迟停止操作直到一切都完成。 中间件还会在停止阶段短路所有请求。 但这个解决方案对我来说听起来不太好。

我结束了中间件的建议方法:

 public class ShutDownMiddleware { private readonly Func, Task> next; private static int requestCount = 0; private static bool shutDownStateOn = false; public static void ShutDown() { shutDownStateOn = true; } public static int GetRequestCount() { return requestCount; } public ShutDownMiddleware(Func, Task> next) { this.next = next; } public async Task Invoke(IDictionary environment) { if (shutDownStateOn) { environment["owin.ResponseStatusCode"] = HttpStatusCode.ServiceUnavailable; return; } Interlocked.Increment(ref requestCount); try { await next.Invoke(environment); } finally { Interlocked.Decrement(ref requestCount); } } } 

这被注册为管道中的第一个中间件,在程序的主要方法中我可以像这样使用它:

 public class Program { public static ManualResetEventSlim StopSwitch = new ManualResetEventSlim(); static void Main(string[] args) { Console.CancelKeyPress += (s, a) => { a.Cancel = true; StopSwitch.Set(); }; using (WebApp.Start("http://+:8080/")) { Console.WriteLine("Server is running..."); Console.WriteLine("Press CTRL+C to stop it."); StopSwitch.Wait(); Console.WriteLine("Server is stopping..."); ShutDownMiddleware.ShutDown(); while (ShutDownMiddleware.GetRequestCount() != 0) { Thread.Sleep(TimeSpan.FromSeconds(1)); } } } } 

我也发现了这个: https : //katanaproject.codeplex.com/workitem/281他们正在谈论类似的方法。