创build针对Linux Docker容器的长期运行的.NET Core服务

似乎有两种实质性的.NET Core项目:ASP.NET Core Web App和Console App。 我想在一个Docker环境(Linux容器)中构build一个类似Windows服务的东西,这个过程开始的地方无限期地运行,并且只在被告知的时候停止。 这两个项目types都不适合。 我错过了什么吗?

这两种types的应用程序都是有意义的,这取决于您如何计划与此服务进行通信。

如果你想通过一些TCP端口上的标准HTTP与它进行通信,那么使用ASP.Net核心Web应用程序将使事情变得简单。

如果你想通过一些比RabbitMQ,Kafka,原始TCP套接字或其他东西更“奇特”的方式进行通信,那么Console Application就是你想要的。 正如Gareth Luckett的答案所指出的,诀窍就是确保你的mainfunction块。 正在运行的Docker容器只要容器应该运行,就会期望主线程阻塞。

“控制台”这个词在这里可能有些误导。 微软使用它来区分它与“GUI”应用程序(如WinForms,WPF,UWP,Xamarin等)或通过IIS带来的Web应用程序。 ASP.NET核心应用程序只是带有库的控制台应用程序来托pipeWeb服务器。

所以对于你的应用程序,“控制台”是你想要的项目types。 正如@mason所提到的,即使Windows服务也只是“控制台”应用程序 – 一个不是GUI应用程序的.exe文件。

不幸的是,由于控制台应用程序在运行时需要stdin,因此通过docker它将立即退出。 你可以使用asp.net“托pipe”它。

 public class Program { public static ManualResetEventSlim Done = new ManualResetEventSlim(false); public static void Main(string[] args) { //This is unbelievably complex because .NET Core Console.ReadLine() does not block in a docker container...! var host = new WebHostBuilder().UseStartup(typeof(Startup)).Build(); using (CancellationTokenSource cts = new CancellationTokenSource()) { Action shutdown = () => { if (!cts.IsCancellationRequested) { Console.WriteLine("Application is shutting down..."); cts.Cancel(); } Done.Wait(); }; Console.CancelKeyPress += (sender, eventArgs) => { shutdown(); // Don't terminate the process immediately, wait for the Main thread to exit gracefully. eventArgs.Cancel = true; }; host.Run(cts.Token); Done.Set(); } } } 

启动类:

 public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IServer, ConsoleAppRunner>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { } } 

ConsoleAppRunner类

 public class ConsoleAppRunner : IServer { /// <summary>A collection of HTTP features of the server.</summary> public IFeatureCollection Features { get; } public ConsoleAppRunner(ILoggerFactory loggerFactory) { Features = new FeatureCollection(); } /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> public void Dispose() { } /// <summary>Start the server with an application.</summary> /// <param name="application">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.Server.IHttpApplication`1" />.</param> /// <typeparam name="TContext">The context associated with the application.</typeparam> public void Start<TContext>(IHttpApplication<TContext> application) { //Actual program code starts here... Console.WriteLine("Demo app running..."); Program.Done.Wait(); // <-- Keeps the program running - The Done property is a ManualResetEventSlim instance which gets set if someone terminates the program. } } 

来源: https : //stackoverflow.com/a/40549512/2238275