2017-06-14 46 views
3

似乎有兩種類型的實質性.NET Core項目:ASP.NET Core Web App和控制檯應用程序。我想在Docker環境(Linux容器)中構建類似Windows服務的東西,該過程開始的地方無限期地運行,並且僅在被告知時停止。這兩種項目類型都不適合。我錯過了什麼嗎?創建長期運行的針對Linux Docker容器的.NET Core服務

+3

Windows服務基本上是由服務管理器啓動/停止的控制檯應用程序。 – mason

回答

3

這兩種類型的應用程序是有意義的,這取決於你如何計劃與溝通這項服務。

如果您想通過某個TCP端口上的標準HTTP與它進行通信,那麼使用ASP.Net核心Web應用程序將使事情更輕鬆。

如果你想通過一些像RabbitMQ,Kafka,原始TCP套接字或其他東西那樣的「異國情調」進行通信,那麼控制檯應用程序就是你想要的。正如Gareth Luckett的回答指出的那樣,訣竅就是確保您的main功能塊。正在運行的Docker容器只要容器應該運行,就會期望主線程阻塞。

4

術語「控制檯」在這裏可能有點誤導。微軟使用它來將它與「GUI」應用程序(如WinForms,WPF,UWP,Xamarin等)或通過IIS提供的Web應用程序區分開來。 ASP.NET Core應用程序只是包含用於託管Web服務器的庫的控制檯應用程序。

因此對於您的應用程序,「控制檯」是您想要的項目類型。正如@mason所提到的,即使Windows服務也只是「控制檯」應用程序 - 一個不是GUI應用程序的.exe文件。

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

啓動類:

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

相關問題