Create a long term .NET Core service targeting Linux Docker container

There seem to be two types of main .NET Core project: ASP.NET Core Web App and Console App. I would like to build something like Windows Service in a Docker environment (Linux container) where the process starts, runs indefinitely and only stops when it is transferred. None of the project types are suitable. Did I miss something?

+3


source to share


3 answers


Both types of applications make sense, it depends on how you plan to communicate with this service.

If you want to communicate with it over the HTTP standard on some TCP port, then using an ASP.Net Core web app will make things easier.



If you want to communicate over something more "exotic" like RabbitMQ, Kafka, raw TCP sockets, or whatever, then a console application is what you want. The trick, as Gareth Luckett points out, is to make sure your function blocks are main

. In a running Docker container, the main thread is expected to be blocked while the container is supposed to be running.

+3


source


The term "console" can be a little misleading. Microsoft uses it to differentiate it from "GUI" applications (such as WinForms, WPF, UWP, Xamarin, etc.) or web applications that are streamed over IIS. ASP.NET Core apps are simply console apps with libraries to host the web server.



So, for your application, "console" is the type of project you want. As @mason mentioned, even Windows Services are just "console" applications .exe file, which is not a graphical application.

+4


source


Unfortunately, stdin is required as a console application on startup, via docker it will exit immediately. You can "host" it with 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();
        }
    }      
}

      

Launch class:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IServer, ConsoleAppRunner>();
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

      

ConsoleAppRunner class

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.

    }
}

      

Source: fooobar.com/questions/559336 / ...

+2


source







All Articles