2017-08-31 90 views
5

我试图让一个Grpc服务器作为一个控制台守护进程运行。这个gRPC服务器是一个在Docker容器中运行的微服务。保持Dotnet Core Grpc服务器作为控制台应用程序运行?

所有的例子我能找到使用下列内容:

Console.ReadKey(); 

这确实阻塞主线程,并使其保持运行,但在泊坞窗,出现以下错误不起作用:

"Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read." 

现在我可以尝试为docker专门找到解决方法,但这仍然不太合适。有没有人知道一个好的“生产准备”方法来保持服​​务的运行?

+0

如果您在启动时使用'-it'它会工作码头集装箱。如果这不适合你,你可以通过'Thread.Sleep(Timeout.Infinite)' –

+0

无限期地睡主线程。Docker容器被部署到云平台上的kubernetes集群中。交互容器不是一个选项。 Thread.Sleep的问题在于,例如当容器停止时grpc服务器没有正常关闭。 –

回答

5

使用ManualResetEvent来阻止主线程,直到收到关闭事件。

例如,在一个简单的情况:

class Program 
{ 
    public static ManualResetEvent Shutdown = new ManualResetEvent(false); 

    static void Main(string[] args) 
    { 
    Task.Run(() => 
    { 
     Console.WriteLine("Waiting in other thread..."); 
     Thread.Sleep(2000); 
     Shutdown.Set(); 
    }); 

    Console.WriteLine("Waiting for signal"); 
    Shutdown.WaitOne(); 

    Console.WriteLine("Resolved"); 
    } 
} 

例如,在你的情况,我想是这样的:

using System; 
using System.Net.Sockets; 
using System.Threading; 
using System.Threading.Tasks; 
using Grpc.Core; 
using Helloworld; 

namespace GreeterServer 
{ 
    class GreeterImpl : Greeter.GreeterBase 
    { 
    // Server side handler of the SayHello RPC 
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) 
    { 
     Program.Shutdown.Set(); // <--- Signals the main thread to continue 
     return Task.FromResult(new HelloReply {Message = "Hello " + request.Name}); 
    } 
    } 

    class Program 
    { 
    const int Port = 50051; 

    public static ManualResetEvent Shutdown = new ManualResetEvent(false); 

    public static void Main(string[] args) 
    { 
     Server server = new Server 
     { 
     Services = {Greeter.BindService(new GreeterImpl())}, 
     Ports = {new ServerPort("localhost", Port, ServerCredentials.Insecure)} 
     }; 
     server.Start(); 

     Shutdown.WaitOne(); // <--- Waits for ever or signal received 

     server.ShutdownAsync().Wait(); 
    } 
    } 
} 
+0

要试一试,并且会让你更新。谢谢! –

+0

也可以使用'async Main'并使用'TaskCompletionSource'对象,这样可以释放主线程以执行其他工作。 – VMAtm

相关问题