docker container exits immediately even with Console.ReadLine() in a .net core console application











up vote
13
down vote

favorite
1












I am trying to run a .net core 1.0.0 console application inside a docker container.

When I run dotnet run command from inside the Demo folder on my machine, it works fine; But when run using docker run -d --name demo Demo, the container exits immediately.



I tried docker logs demo to check the logs and it just shows the text from the Console.WriteLine:




Demo app running...




and nothing else.



I have uploaded the project at https://github.com/learningdockerandnetcore/Demo



The project contains Programs.cs, Dockerfile used to create Demo image, and project.json file.










share|improve this question
























  • I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
    – hdz
    Jul 24 '16 at 7:05












  • also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
    – hdz
    Jul 24 '16 at 7:08

















up vote
13
down vote

favorite
1












I am trying to run a .net core 1.0.0 console application inside a docker container.

When I run dotnet run command from inside the Demo folder on my machine, it works fine; But when run using docker run -d --name demo Demo, the container exits immediately.



I tried docker logs demo to check the logs and it just shows the text from the Console.WriteLine:




Demo app running...




and nothing else.



I have uploaded the project at https://github.com/learningdockerandnetcore/Demo



The project contains Programs.cs, Dockerfile used to create Demo image, and project.json file.










share|improve this question
























  • I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
    – hdz
    Jul 24 '16 at 7:05












  • also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
    – hdz
    Jul 24 '16 at 7:08















up vote
13
down vote

favorite
1









up vote
13
down vote

favorite
1






1





I am trying to run a .net core 1.0.0 console application inside a docker container.

When I run dotnet run command from inside the Demo folder on my machine, it works fine; But when run using docker run -d --name demo Demo, the container exits immediately.



I tried docker logs demo to check the logs and it just shows the text from the Console.WriteLine:




Demo app running...




and nothing else.



I have uploaded the project at https://github.com/learningdockerandnetcore/Demo



The project contains Programs.cs, Dockerfile used to create Demo image, and project.json file.










share|improve this question















I am trying to run a .net core 1.0.0 console application inside a docker container.

When I run dotnet run command from inside the Demo folder on my machine, it works fine; But when run using docker run -d --name demo Demo, the container exits immediately.



I tried docker logs demo to check the logs and it just shows the text from the Console.WriteLine:




Demo app running...




and nothing else.



I have uploaded the project at https://github.com/learningdockerandnetcore/Demo



The project contains Programs.cs, Dockerfile used to create Demo image, and project.json file.







c# docker asp.net-core dockerfile .net-core






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 12 '17 at 12:41









Hakam Fostok

5,05583763




5,05583763










asked Jul 24 '16 at 5:22









Learning Docker

143128




143128












  • I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
    – hdz
    Jul 24 '16 at 7:05












  • also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
    – hdz
    Jul 24 '16 at 7:08




















  • I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
    – hdz
    Jul 24 '16 at 7:05












  • also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
    – hdz
    Jul 24 '16 at 7:08


















I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
– hdz
Jul 24 '16 at 7:05






I'm trying to learn myself: I think you want to run it in interactive mode and probably want to add a term. docker run -it --name demo Demo
– hdz
Jul 24 '16 at 7:05














also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
– hdz
Jul 24 '16 at 7:08






also you can attach to it docker attach {container} to get back to it if you run it in background mode(-d). You won't see the output as it already output that but you will be able to press enter for the container to exit
– hdz
Jul 24 '16 at 7:08














7 Answers
7






active

oldest

votes

















up vote
7
down vote



accepted










You should either run your container in the Interactive mode (with -i option). but please note that the background processes will be closed immediately when you run the container so make sure your script is run in the foreground or it simply won't work.






share|improve this answer























  • Isn't -i Interactive mode - not daemon (or detached) mode?
    – Jay
    Nov 9 '16 at 10:18










  • Yes, -d is deamon/detached mode.
    – Peter
    Feb 20 '17 at 7:45












  • -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
    – lanwin
    Jul 5 at 9:47




















up vote
10
down vote













The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!



Doing it this way will run in Docker using the docker run -d option, so you don't have to have a live connection to keep the STDIN stream alive.



I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:



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();
}
}
}


The Startup class:



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


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


The 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.

}
}


The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.



Edit 30th Oct 2018
This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.






share|improve this answer






























    up vote
    8
    down vote













    If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.



    In order to run your app, you should implement your own IHostedService interface or inherit from the BackgroundService class, then add it to host context within ConfigureServices.



    namespace Microsoft.Extensions.Hosting
    {
    //
    // Summary:
    // Defines methods for objects that are managed by the host.
    public interface IHostedService
    {
    // Summary:
    // Triggered when the application host is ready to start the service.
    Task StartAsync(CancellationToken cancellationToken);

    // Summary:
    // Triggered when the application host is performing a graceful shutdown.
    Task StopAsync(CancellationToken cancellationToken);
    }
    }


    Here's a sample hosted service:



    public class TimedHostedService : IHostedService, IDisposable
    {
    private readonly ILogger _logger;
    private Timer _timer;

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
    _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
    _logger.LogInformation("Timed Background Service is starting.");

    _timer = new Timer(DoWork, null, TimeSpan.Zero,
    TimeSpan.FromSeconds(5));

    return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
    _logger.LogInformation("Timed Background Service is working.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
    _logger.LogInformation("Timed Background Service is stopping.");

    _timer?.Change(Timeout.Infinite, 0);

    return Task.CompletedTask;
    }

    public void Dispose()
    {
    _timer?.Dispose();
    }
    }


    Then creating the HostBuilder and adding the service and other componments (logging, configuration).



    public class Program
    {
    public static async Task Main(string args)
    {
    var hostBuilder = new HostBuilder()
    // Add configuration, logging, ...
    .ConfigureServices((hostContext, services) =>
    {
    // Add your services with depedency injection.
    });

    await hostBuilder.RunConsoleAsync();
    }
    }





    share|improve this answer























    • Great post; much appreciated.
      – Daniel
      Jun 14 at 5:41










    • Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
      – gaurav thakur
      Jul 18 at 4:00










    • Not sure about service account. This console app can run on windows and Linux container
      – Feiyu Zhou
      Jul 18 at 4:57










    • @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
      – gaurav thakur
      Jul 19 at 8:57










    • @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
      – Feiyu Zhou
      Jul 19 at 15:30


















    up vote
    1
    down vote













    You can use:



    Thread.Sleep(Timeout.Infinite);



    See this answer:



    Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?






    share|improve this answer




























      up vote
      0
      down vote













      one more "dirty way" is to start your program in screen using



      screen -dmS yourprogramm





      share|improve this answer




























        up vote
        0
        down vote













        I am not sure why Console.ReadLine(); doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register a ConsoleCancelEventHandler with the Console.CancelKeyPress event.



        Then you can instead block the main thread with a type of Threading WaitHandle and signal the release of the main thread when Console.CancelKeyPress is fired.



        A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5






        share|improve this answer




























          up vote
          0
          down vote













          Using Console.ReadLine instead seems to work.



          C#:



          do
          {
          Console.WriteLine($"Type: quit<Enter> to end {Process.GetCurrentProcess().ProcessName}");
          }
          while (!Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase));


          F#:



          while not (Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase)) do
          printfn "Type: quit<Enter> to end"





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38549006%2fdocker-container-exits-immediately-even-with-console-readline-in-a-net-core-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            7 Answers
            7






            active

            oldest

            votes








            7 Answers
            7






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            7
            down vote



            accepted










            You should either run your container in the Interactive mode (with -i option). but please note that the background processes will be closed immediately when you run the container so make sure your script is run in the foreground or it simply won't work.






            share|improve this answer























            • Isn't -i Interactive mode - not daemon (or detached) mode?
              – Jay
              Nov 9 '16 at 10:18










            • Yes, -d is deamon/detached mode.
              – Peter
              Feb 20 '17 at 7:45












            • -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
              – lanwin
              Jul 5 at 9:47

















            up vote
            7
            down vote



            accepted










            You should either run your container in the Interactive mode (with -i option). but please note that the background processes will be closed immediately when you run the container so make sure your script is run in the foreground or it simply won't work.






            share|improve this answer























            • Isn't -i Interactive mode - not daemon (or detached) mode?
              – Jay
              Nov 9 '16 at 10:18










            • Yes, -d is deamon/detached mode.
              – Peter
              Feb 20 '17 at 7:45












            • -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
              – lanwin
              Jul 5 at 9:47















            up vote
            7
            down vote



            accepted







            up vote
            7
            down vote



            accepted






            You should either run your container in the Interactive mode (with -i option). but please note that the background processes will be closed immediately when you run the container so make sure your script is run in the foreground or it simply won't work.






            share|improve this answer














            You should either run your container in the Interactive mode (with -i option). but please note that the background processes will be closed immediately when you run the container so make sure your script is run in the foreground or it simply won't work.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 6 '17 at 12:37









            William Haggerty

            434




            434










            answered Jul 24 '16 at 8:47









            Miad Abrin

            827513




            827513












            • Isn't -i Interactive mode - not daemon (or detached) mode?
              – Jay
              Nov 9 '16 at 10:18










            • Yes, -d is deamon/detached mode.
              – Peter
              Feb 20 '17 at 7:45












            • -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
              – lanwin
              Jul 5 at 9:47




















            • Isn't -i Interactive mode - not daemon (or detached) mode?
              – Jay
              Nov 9 '16 at 10:18










            • Yes, -d is deamon/detached mode.
              – Peter
              Feb 20 '17 at 7:45












            • -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
              – lanwin
              Jul 5 at 9:47


















            Isn't -i Interactive mode - not daemon (or detached) mode?
            – Jay
            Nov 9 '16 at 10:18




            Isn't -i Interactive mode - not daemon (or detached) mode?
            – Jay
            Nov 9 '16 at 10:18












            Yes, -d is deamon/detached mode.
            – Peter
            Feb 20 '17 at 7:45






            Yes, -d is deamon/detached mode.
            – Peter
            Feb 20 '17 at 7:45














            -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
            – lanwin
            Jul 5 at 9:47






            -i means that Docker provides a StandardInput to the process. That is independent from detached mode. The default behavior of Console.ReadLine if no StandardInput is present, is to return null instead of blocking.
            – lanwin
            Jul 5 at 9:47














            up vote
            10
            down vote













            The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!



            Doing it this way will run in Docker using the docker run -d option, so you don't have to have a live connection to keep the STDIN stream alive.



            I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:



            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();
            }
            }
            }


            The Startup class:



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


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


            The 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.

            }
            }


            The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.



            Edit 30th Oct 2018
            This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.






            share|improve this answer



























              up vote
              10
              down vote













              The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!



              Doing it this way will run in Docker using the docker run -d option, so you don't have to have a live connection to keep the STDIN stream alive.



              I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:



              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();
              }
              }
              }


              The Startup class:



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


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


              The 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.

              }
              }


              The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.



              Edit 30th Oct 2018
              This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.






              share|improve this answer

























                up vote
                10
                down vote










                up vote
                10
                down vote









                The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!



                Doing it this way will run in Docker using the docker run -d option, so you don't have to have a live connection to keep the STDIN stream alive.



                I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:



                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();
                }
                }
                }


                The Startup class:



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


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


                The 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.

                }
                }


                The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.



                Edit 30th Oct 2018
                This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.






                share|improve this answer














                The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!



                Doing it this way will run in Docker using the docker run -d option, so you don't have to have a live connection to keep the STDIN stream alive.



                I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:



                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();
                }
                }
                }


                The Startup class:



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


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


                The 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.

                }
                }


                The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.



                Edit 30th Oct 2018
                This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Oct 30 at 8:21

























                answered Nov 11 '16 at 13:56









                Jay

                3,91132948




                3,91132948






















                    up vote
                    8
                    down vote













                    If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.



                    In order to run your app, you should implement your own IHostedService interface or inherit from the BackgroundService class, then add it to host context within ConfigureServices.



                    namespace Microsoft.Extensions.Hosting
                    {
                    //
                    // Summary:
                    // Defines methods for objects that are managed by the host.
                    public interface IHostedService
                    {
                    // Summary:
                    // Triggered when the application host is ready to start the service.
                    Task StartAsync(CancellationToken cancellationToken);

                    // Summary:
                    // Triggered when the application host is performing a graceful shutdown.
                    Task StopAsync(CancellationToken cancellationToken);
                    }
                    }


                    Here's a sample hosted service:



                    public class TimedHostedService : IHostedService, IDisposable
                    {
                    private readonly ILogger _logger;
                    private Timer _timer;

                    public TimedHostedService(ILogger<TimedHostedService> logger)
                    {
                    _logger = logger;
                    }

                    public Task StartAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is starting.");

                    _timer = new Timer(DoWork, null, TimeSpan.Zero,
                    TimeSpan.FromSeconds(5));

                    return Task.CompletedTask;
                    }

                    private void DoWork(object state)
                    {
                    _logger.LogInformation("Timed Background Service is working.");
                    }

                    public Task StopAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is stopping.");

                    _timer?.Change(Timeout.Infinite, 0);

                    return Task.CompletedTask;
                    }

                    public void Dispose()
                    {
                    _timer?.Dispose();
                    }
                    }


                    Then creating the HostBuilder and adding the service and other componments (logging, configuration).



                    public class Program
                    {
                    public static async Task Main(string args)
                    {
                    var hostBuilder = new HostBuilder()
                    // Add configuration, logging, ...
                    .ConfigureServices((hostContext, services) =>
                    {
                    // Add your services with depedency injection.
                    });

                    await hostBuilder.RunConsoleAsync();
                    }
                    }





                    share|improve this answer























                    • Great post; much appreciated.
                      – Daniel
                      Jun 14 at 5:41










                    • Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                      – gaurav thakur
                      Jul 18 at 4:00










                    • Not sure about service account. This console app can run on windows and Linux container
                      – Feiyu Zhou
                      Jul 18 at 4:57










                    • @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                      – gaurav thakur
                      Jul 19 at 8:57










                    • @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                      – Feiyu Zhou
                      Jul 19 at 15:30















                    up vote
                    8
                    down vote













                    If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.



                    In order to run your app, you should implement your own IHostedService interface or inherit from the BackgroundService class, then add it to host context within ConfigureServices.



                    namespace Microsoft.Extensions.Hosting
                    {
                    //
                    // Summary:
                    // Defines methods for objects that are managed by the host.
                    public interface IHostedService
                    {
                    // Summary:
                    // Triggered when the application host is ready to start the service.
                    Task StartAsync(CancellationToken cancellationToken);

                    // Summary:
                    // Triggered when the application host is performing a graceful shutdown.
                    Task StopAsync(CancellationToken cancellationToken);
                    }
                    }


                    Here's a sample hosted service:



                    public class TimedHostedService : IHostedService, IDisposable
                    {
                    private readonly ILogger _logger;
                    private Timer _timer;

                    public TimedHostedService(ILogger<TimedHostedService> logger)
                    {
                    _logger = logger;
                    }

                    public Task StartAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is starting.");

                    _timer = new Timer(DoWork, null, TimeSpan.Zero,
                    TimeSpan.FromSeconds(5));

                    return Task.CompletedTask;
                    }

                    private void DoWork(object state)
                    {
                    _logger.LogInformation("Timed Background Service is working.");
                    }

                    public Task StopAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is stopping.");

                    _timer?.Change(Timeout.Infinite, 0);

                    return Task.CompletedTask;
                    }

                    public void Dispose()
                    {
                    _timer?.Dispose();
                    }
                    }


                    Then creating the HostBuilder and adding the service and other componments (logging, configuration).



                    public class Program
                    {
                    public static async Task Main(string args)
                    {
                    var hostBuilder = new HostBuilder()
                    // Add configuration, logging, ...
                    .ConfigureServices((hostContext, services) =>
                    {
                    // Add your services with depedency injection.
                    });

                    await hostBuilder.RunConsoleAsync();
                    }
                    }





                    share|improve this answer























                    • Great post; much appreciated.
                      – Daniel
                      Jun 14 at 5:41










                    • Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                      – gaurav thakur
                      Jul 18 at 4:00










                    • Not sure about service account. This console app can run on windows and Linux container
                      – Feiyu Zhou
                      Jul 18 at 4:57










                    • @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                      – gaurav thakur
                      Jul 19 at 8:57










                    • @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                      – Feiyu Zhou
                      Jul 19 at 15:30













                    up vote
                    8
                    down vote










                    up vote
                    8
                    down vote









                    If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.



                    In order to run your app, you should implement your own IHostedService interface or inherit from the BackgroundService class, then add it to host context within ConfigureServices.



                    namespace Microsoft.Extensions.Hosting
                    {
                    //
                    // Summary:
                    // Defines methods for objects that are managed by the host.
                    public interface IHostedService
                    {
                    // Summary:
                    // Triggered when the application host is ready to start the service.
                    Task StartAsync(CancellationToken cancellationToken);

                    // Summary:
                    // Triggered when the application host is performing a graceful shutdown.
                    Task StopAsync(CancellationToken cancellationToken);
                    }
                    }


                    Here's a sample hosted service:



                    public class TimedHostedService : IHostedService, IDisposable
                    {
                    private readonly ILogger _logger;
                    private Timer _timer;

                    public TimedHostedService(ILogger<TimedHostedService> logger)
                    {
                    _logger = logger;
                    }

                    public Task StartAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is starting.");

                    _timer = new Timer(DoWork, null, TimeSpan.Zero,
                    TimeSpan.FromSeconds(5));

                    return Task.CompletedTask;
                    }

                    private void DoWork(object state)
                    {
                    _logger.LogInformation("Timed Background Service is working.");
                    }

                    public Task StopAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is stopping.");

                    _timer?.Change(Timeout.Infinite, 0);

                    return Task.CompletedTask;
                    }

                    public void Dispose()
                    {
                    _timer?.Dispose();
                    }
                    }


                    Then creating the HostBuilder and adding the service and other componments (logging, configuration).



                    public class Program
                    {
                    public static async Task Main(string args)
                    {
                    var hostBuilder = new HostBuilder()
                    // Add configuration, logging, ...
                    .ConfigureServices((hostContext, services) =>
                    {
                    // Add your services with depedency injection.
                    });

                    await hostBuilder.RunConsoleAsync();
                    }
                    }





                    share|improve this answer














                    If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.



                    In order to run your app, you should implement your own IHostedService interface or inherit from the BackgroundService class, then add it to host context within ConfigureServices.



                    namespace Microsoft.Extensions.Hosting
                    {
                    //
                    // Summary:
                    // Defines methods for objects that are managed by the host.
                    public interface IHostedService
                    {
                    // Summary:
                    // Triggered when the application host is ready to start the service.
                    Task StartAsync(CancellationToken cancellationToken);

                    // Summary:
                    // Triggered when the application host is performing a graceful shutdown.
                    Task StopAsync(CancellationToken cancellationToken);
                    }
                    }


                    Here's a sample hosted service:



                    public class TimedHostedService : IHostedService, IDisposable
                    {
                    private readonly ILogger _logger;
                    private Timer _timer;

                    public TimedHostedService(ILogger<TimedHostedService> logger)
                    {
                    _logger = logger;
                    }

                    public Task StartAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is starting.");

                    _timer = new Timer(DoWork, null, TimeSpan.Zero,
                    TimeSpan.FromSeconds(5));

                    return Task.CompletedTask;
                    }

                    private void DoWork(object state)
                    {
                    _logger.LogInformation("Timed Background Service is working.");
                    }

                    public Task StopAsync(CancellationToken cancellationToken)
                    {
                    _logger.LogInformation("Timed Background Service is stopping.");

                    _timer?.Change(Timeout.Infinite, 0);

                    return Task.CompletedTask;
                    }

                    public void Dispose()
                    {
                    _timer?.Dispose();
                    }
                    }


                    Then creating the HostBuilder and adding the service and other componments (logging, configuration).



                    public class Program
                    {
                    public static async Task Main(string args)
                    {
                    var hostBuilder = new HostBuilder()
                    // Add configuration, logging, ...
                    .ConfigureServices((hostContext, services) =>
                    {
                    // Add your services with depedency injection.
                    });

                    await hostBuilder.RunConsoleAsync();
                    }
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Aug 2 at 13:27

























                    answered May 9 at 3:32









                    Feiyu Zhou

                    1,1031316




                    1,1031316












                    • Great post; much appreciated.
                      – Daniel
                      Jun 14 at 5:41










                    • Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                      – gaurav thakur
                      Jul 18 at 4:00










                    • Not sure about service account. This console app can run on windows and Linux container
                      – Feiyu Zhou
                      Jul 18 at 4:57










                    • @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                      – gaurav thakur
                      Jul 19 at 8:57










                    • @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                      – Feiyu Zhou
                      Jul 19 at 15:30


















                    • Great post; much appreciated.
                      – Daniel
                      Jun 14 at 5:41










                    • Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                      – gaurav thakur
                      Jul 18 at 4:00










                    • Not sure about service account. This console app can run on windows and Linux container
                      – Feiyu Zhou
                      Jul 18 at 4:57










                    • @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                      – gaurav thakur
                      Jul 19 at 8:57










                    • @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                      – Feiyu Zhou
                      Jul 19 at 15:30
















                    Great post; much appreciated.
                    – Daniel
                    Jun 14 at 5:41




                    Great post; much appreciated.
                    – Daniel
                    Jun 14 at 5:41












                    Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                    – gaurav thakur
                    Jul 18 at 4:00




                    Great answer. One more thing how can I run this console application by a service account? I am deploying it on Linxu container
                    – gaurav thakur
                    Jul 18 at 4:00












                    Not sure about service account. This console app can run on windows and Linux container
                    – Feiyu Zhou
                    Jul 18 at 4:57




                    Not sure about service account. This console app can run on windows and Linux container
                    – Feiyu Zhou
                    Jul 18 at 4:57












                    @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                    – gaurav thakur
                    Jul 19 at 8:57




                    @FeiyuZhou yes it runs on Linux container without any issues. What I meant was to set the user of the app to service account. Currently it runs by default user which doesn't have rights to write on our fileSharer servers. Any idea?
                    – gaurav thakur
                    Jul 19 at 8:57












                    @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                    – Feiyu Zhou
                    Jul 19 at 15:30




                    @gauravthakur Maybe you can try to run it as windows service: ben-morris.com/…
                    – Feiyu Zhou
                    Jul 19 at 15:30










                    up vote
                    1
                    down vote













                    You can use:



                    Thread.Sleep(Timeout.Infinite);



                    See this answer:



                    Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?






                    share|improve this answer

























                      up vote
                      1
                      down vote













                      You can use:



                      Thread.Sleep(Timeout.Infinite);



                      See this answer:



                      Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?






                      share|improve this answer























                        up vote
                        1
                        down vote










                        up vote
                        1
                        down vote









                        You can use:



                        Thread.Sleep(Timeout.Infinite);



                        See this answer:



                        Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?






                        share|improve this answer












                        You can use:



                        Thread.Sleep(Timeout.Infinite);



                        See this answer:



                        Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Oct 16 '17 at 14:58









                        Tjaart

                        1,80512550




                        1,80512550






















                            up vote
                            0
                            down vote













                            one more "dirty way" is to start your program in screen using



                            screen -dmS yourprogramm





                            share|improve this answer

























                              up vote
                              0
                              down vote













                              one more "dirty way" is to start your program in screen using



                              screen -dmS yourprogramm





                              share|improve this answer























                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                one more "dirty way" is to start your program in screen using



                                screen -dmS yourprogramm





                                share|improve this answer












                                one more "dirty way" is to start your program in screen using



                                screen -dmS yourprogramm






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Mar 12 '17 at 11:48









                                Dmitry Loktionov

                                1




                                1






















                                    up vote
                                    0
                                    down vote













                                    I am not sure why Console.ReadLine(); doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register a ConsoleCancelEventHandler with the Console.CancelKeyPress event.



                                    Then you can instead block the main thread with a type of Threading WaitHandle and signal the release of the main thread when Console.CancelKeyPress is fired.



                                    A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5






                                    share|improve this answer

























                                      up vote
                                      0
                                      down vote













                                      I am not sure why Console.ReadLine(); doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register a ConsoleCancelEventHandler with the Console.CancelKeyPress event.



                                      Then you can instead block the main thread with a type of Threading WaitHandle and signal the release of the main thread when Console.CancelKeyPress is fired.



                                      A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5






                                      share|improve this answer























                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote









                                        I am not sure why Console.ReadLine(); doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register a ConsoleCancelEventHandler with the Console.CancelKeyPress event.



                                        Then you can instead block the main thread with a type of Threading WaitHandle and signal the release of the main thread when Console.CancelKeyPress is fired.



                                        A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5






                                        share|improve this answer












                                        I am not sure why Console.ReadLine(); doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register a ConsoleCancelEventHandler with the Console.CancelKeyPress event.



                                        Then you can instead block the main thread with a type of Threading WaitHandle and signal the release of the main thread when Console.CancelKeyPress is fired.



                                        A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Aug 25 '17 at 8:14









                                        Patrick Burls

                                        11




                                        11






















                                            up vote
                                            0
                                            down vote













                                            Using Console.ReadLine instead seems to work.



                                            C#:



                                            do
                                            {
                                            Console.WriteLine($"Type: quit<Enter> to end {Process.GetCurrentProcess().ProcessName}");
                                            }
                                            while (!Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase));


                                            F#:



                                            while not (Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase)) do
                                            printfn "Type: quit<Enter> to end"





                                            share|improve this answer

























                                              up vote
                                              0
                                              down vote













                                              Using Console.ReadLine instead seems to work.



                                              C#:



                                              do
                                              {
                                              Console.WriteLine($"Type: quit<Enter> to end {Process.GetCurrentProcess().ProcessName}");
                                              }
                                              while (!Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase));


                                              F#:



                                              while not (Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase)) do
                                              printfn "Type: quit<Enter> to end"





                                              share|improve this answer























                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                Using Console.ReadLine instead seems to work.



                                                C#:



                                                do
                                                {
                                                Console.WriteLine($"Type: quit<Enter> to end {Process.GetCurrentProcess().ProcessName}");
                                                }
                                                while (!Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase));


                                                F#:



                                                while not (Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase)) do
                                                printfn "Type: quit<Enter> to end"





                                                share|improve this answer












                                                Using Console.ReadLine instead seems to work.



                                                C#:



                                                do
                                                {
                                                Console.WriteLine($"Type: quit<Enter> to end {Process.GetCurrentProcess().ProcessName}");
                                                }
                                                while (!Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase));


                                                F#:



                                                while not (Console.ReadLine().Trim().Equals("quit",StringComparison.OrdinalIgnoreCase)) do
                                                printfn "Type: quit<Enter> to end"






                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Jan 23 at 12:06









                                                RusinaRange

                                                114112




                                                114112






























                                                     

                                                    draft saved


                                                    draft discarded



















































                                                     


                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38549006%2fdocker-container-exits-immediately-even-with-console-readline-in-a-net-core-c%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    MongoDB - Not Authorized To Execute Command

                                                    How to fix TextFormField cause rebuild widget in Flutter

                                                    Npm cannot find a required file even through it is in the searched directory