我OWIN服务器的控制台应用程序的一部分。你可以在这里看到的主要方法:
I have OWIN server as part of console app. You can see the main method here:
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<Startup>("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...");
}
}
在处理请求是长一点,并在同一时间的用户presses CTRL + C停止请求处理立即停止,并响应不发送应用程序。是否有可能改变这种行为?我想拒绝所有新的请求,但等到它正在处理的请求完成,之后停止服务器。
When processing of the request is little bit longer and in the same time user presses CTRL+C to stop the application the request processing is stopped immediately and response is not sent. Is it possible to change this behavior? I would like to refuse all new requests but wait until the requests which are currently processing are done and stop server after that.
我最初的想法是创建OWIN中间件将继续要求这是目前处理的轨道,推迟停止动作,直到一切都做。中间件也要在停止相短路的所有请求。但是,这种解决方案听起来不错,我不是。
My initial idea is to create OWIN middleware which will keep track of requests which are currently processing and postpone the stop action until everything is done. Middleware would also short-circuit all requests during the stopping phase. But this solution doesn't sound good to me.
我与中间件的建议的方法结束:
I ended with the suggested approach with the middleware:
public class ShutDownMiddleware
{
private readonly Func<IDictionary<string, object>, 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<IDictionary<string, object>, Task> next)
{
this.next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
if (shutDownStateOn)
{
environment["owin.ResponseStatusCode"] = HttpStatusCode.ServiceUnavailable;
return;
}
Interlocked.Increment(ref requestCount);
try
{
await next.Invoke(environment);
}
finally
{
Interlocked.Decrement(ref requestCount);
}
}
}
这是登记在管道中的第一个中间件和程序的主要方法,我可以用它是这样的:
This is registered as a first middleware in the pipeline and in the main method of program I can use it like this:
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<Startup>("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.$c$cplex.com/workitem / 281 他们谈论类似的做法。
I also found this: https://katanaproject.codeplex.com/workitem/281 They are talking about similar approach.
上一篇:WPF prevent弹出窗口移除文本框的焦点窗口移除、文本框、弹出窗口、窗口
下一篇:ClassCastException异常:不能转换为android.app.Activity转换为、异常、ClassCastException、Activity