似乎有两种类型的实质性.NET Core项目:ASP.NET Core Web App和Console App。我想在Docker环境(Linux容器)中构建类似Windows服务的东西,其中进程启动,无限期运行,并且仅在被告知时停止。两种项目类型似乎都不合适。我错过了什么吗?
答案 0 :(得分:4)
术语"控制台"可能在这里有点误导。微软使用它来区分它" GUI"应用程序(如WinForms,WPF,UWP,Xamarin等)或通过IIS引入的Web应用程序。 ASP.NET核心应用程序只是具有用于托管Web服务器的库的控制台应用程序。
因此,对于您的应用,一个"控制台"是您想要的项目类型。正如@mason所提到的,即使是Windows服务也只是" console"应用程序 - 不是GUI应用程序的.exe文件。
答案 1 :(得分:4)
这两种类型的应用程序都有意义,这取决于您计划如何与此服务进行通信。
如果您想在某些TCP端口上通过标准HTTP与之通信,那么使用ASP.Net核心Web应用程序将使事情变得更容易。
如果你想通过更多的东西进行交流"异国情调"像RabbitMQ,Kafka,原始TCP套接字或其他东西,然后控制台应用程序是你想要的。正如Gareth Luckett的回答指出的那样,诀窍就是确保你的main
功能块。只要容器应该运行,运行的Docker容器就会阻止主线程阻塞。
答案 2 :(得分:2)
不幸的是,控制台应用程序在运行时需要stdin,通过docker它会立即退出。你可以托管'它使用asp.net。
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();
}
}
}
Startup类:
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.
}
}