2017-08-31 16 views
5

Tôi đang cố giữ một máy chủ Grpc chạy như một giao diện điều khiển. Máy chủ gRPC này là một dịch vụ microservice chạy trong một thùng chứa docker.Giữ máy chủ Netnet của Dotnet Core chạy dưới dạng ứng dụng giao diện điều khiển?

Tất cả các ví dụ tôi có thể tìm thấy sử dụng các nội dung sau:

Console.ReadKey(); 

này không thực sự chặn các chủ đề chính và giữ cho nó chạy nhưng không hoạt động trong Docker với các lỗi sau:

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

Bây giờ tôi có thể cố gắng tìm một giải pháp cho docker cụ thể, nhưng điều này vẫn không cảm thấy đúng. Có ai biết về một cách "sẵn sàng sản xuất" tốt để giữ cho dịch vụ hoạt động không?

+0

Nó sẽ có tác dụng nếu bạn sử dụng '-it' khi khởi động các docker container. Nếu điều đó không hiệu quả với bạn, bạn có thể chỉ ngủ thread chính vô thời hạn với 'Thread.Sleep (Timeout.Infinite)' –

+0

Vùng chứa Docker được triển khai thành một cụm kubernetes trên nền tảng đám mây. Các vùng chứa tương tác không phải là một tùy chọn. Vấn đề với Thread.Sleep là không có sự tắt máy duyên dáng của máy chủ grpc khi container được dừng lại chẳng hạn. –

Trả lời

5

Sử dụng ManualResetEvent để chặn luồng chính cho đến khi bạn nhận được sự kiện tắt máy.

Ví dụ trong một tình huống không đáng kể:

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

Ví dụ, trong trường hợp của bạn, tôi tưởng tượng cái gì đó như:

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

Hãy dùng thử và sẽ cập nhật cho bạn. Cảm ơn! –

+0

Một cũng có thể sử dụng 'async Main' và sử dụng đối tượng' TaskCompletionSource' thay vào đó, điều này sẽ giải phóng chủ đề chính cho một số công việc khác cần thực hiện. – VMAtm

Các vấn đề liên quan