我能让 Docker/Linux 保持我的 .NET Core 应用程序存活的唯一方法是欺骗 ASP.NET 为我托管它......这真是一个丑陋的黑客!!
这样做将使用 docker run -d 选项在 Docker 中运行,因此您不必拥有实时连接来保持 STDIN 流处于活动状态。
我创建了一个 .NET Core 控制台应用程序(不是 ASP.NET 应用程序),我的 Program 类如下所示:
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.
}
}
唯一的好处是您可以在应用程序中使用 DI(如果您愿意的话) - 所以在我的用例中,我使用 ILoggingFactory 来处理我的日志记录。
2018 年 10 月 30 日编辑
这篇文章似乎仍然很受欢迎——我想向任何阅读我的旧文章的人指出,它现在已经很古老了。我基于 .NET Core 1.1(当时是新的)。如果您使用的是较新版本的 .NET Core(2.0 / 2.1 或更高版本),现在可能有更好的方法来解决此问题。请花点时间查看此线程上的其他一些帖子,这些帖子的排名可能没有这个高,但可能更新和更新。