2017-05-06 7 views
1

systemd init 시스템에서 작동하는 간단한 에코 서비스를 만들려고합니다. 모두는 괜찮습니다. 빠른 배포 후에도 시작됩니다. 그러나 systemctl status <service> 명령을 통해 상태를 파악하려고 할 때 빠져 나옵니다 (또는 충돌)..NET Core 1.1 콘솔 앱은 우분투에서 systemd 서비스로 항상 종료됩니다/충돌 16.04

Program.cs

using System; 
using System.Threading.Tasks; 

namespace hw 
{ 
    class Program 
    { 
     private const int delay = 1000; 
     private static Random random = new Random(); 

     static async Task Handle() 
     { 
      Console.WriteLine($"tick tack... {random.Next()}"); 
      await Task.Delay(delay); 
      await Handle(); 
     } 

     static void Main(string[] args) 
     { 
      Task.Factory.StartNew(async() => await Handle()); 
      Console.ReadLine(); 
     } 
    } 
} 

hw.service (systemd 설정 파일)

[Unit] 
Description=HW Echo Service 

[Service] 
WorkingDirectory=/var/netcore/hw 
ExecStart=/usr/bin/dotnet /var/netcore/hw/hw.dll 
Restart=always 
RestartSec=10 
SyslogIdentifier=dotnet-echo-hw 

[Install] 
WantedBy=multi-user.target 
:

논리는 내가 다음 소스를 제공하고있어 여기에 간단하다,

Help-script, init.sh (도 사용 가능)) 로컬 시스템에 그것을 시도하려는 경우 :

dotnet build 
dotnet publish 

echo "\nPreparing binaries for the service directory:\n" 
rm -rf /var/netcore/hw 
mkdir /var/netcore /var/netcore/hw 
cp -R bin/Debug/netcoreapp1.1/publish/* /var/netcore/hw 
ls -la /var/netcore/hw 

echo "\nInitializing the systemd service:" 
systemctl stop hw.service 
rm /etc/systemd/system/hw.service 
cp hw.service /etc/systemd/system/hw.service 
systemctl daemon-reload 
systemctl enable hw.service 
systemctl start hw.service 
systemctl status hw.service 

로그 :

내가 뭘 기다리고 있니?

다른 서비스 (ASP.NET 코어)가 실행 중일 때 (활성/녹색 상태) systemd 서비스로 실행하고 싶습니다. ASP.NET 핵심 프로젝트에 관해서는, 거기에 아무런 문제가, 간단한 콘솔에 대한 - 그들은 ...

내 문제를 해결하는 방법? EVK가 ManualResetEvent를 사용하도록 제안하고있다 으로

감사

+0

하지만 비 대화 형 모드로 실행 중이므로 Console.ReadLine이 작동하지 않는다고 가정합니다. ManualResetEvent와 함께 Console.CancelKeyPress 이벤트와 같은 것을 시도해보십시오. – Evk

+0

@Evk 고마워, 네가 나에게 제안한 것과 내 서비스가 지금하고있다. 이전에 대화 형 모드에 대해 알지 못했습니다. 또한 .NET 코어의 현재 버전에는'Environment.UserInteractive' 속성이 없다는 것을 알았습니다. 또한 흥미로운 정보가 여기에 있습니다 : http://stackoverflow.com/questions/43758423/service-detection-for-net-core, 다시 한번 고마워요. 원한다면이 질문에 대한 답을 쓸 수 있습니다. 나는 받아 들일 것입니다. –

+0

도움이 되니 다행이지만, 답변을 쓰는 ​​데는 이유에 대해 정확히 모르겠다. 아직 .net 핵심에 대한 많은 경험이 없다. 예를 들어 전체 .NET에서 Console.ReadLine은 여전히 ​​비 대화식 모드 (차단됨)로 작동하고 Console.ReadKey는 예외를 throw합니다. 여하튼 어떤 입력 (서비스로 실행)을 기대하지 않는다면 Console.ReadLine과 같은 메소드를 사용하지 않는 것이 좋다. – Evk

답변

1

, 나는 다음을 수행했습니다

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace hw 
{ 
    class Program 
    { 
     private const int delay = 1000; 
     private static Random random = new Random(); 
     private static ManualResetEvent resetEvent = new ManualResetEvent(false); 

     static async Task Handle() 
     { 
      Console.WriteLine($"tick tack... {random.Next()}"); 
      await Task.Delay(delay); 
      await Handle(); 
     } 

     static void Main(string[] args) 
     { 
      Task.Factory.StartNew(async() => await Handle()); 
      Console.CancelKeyPress += (sender, eventArgs) => resetEvent.Set(); 
      resetEvent.WaitOne(); 
     } 
    } 
} 

지금 모든/충돌을 중지하지 않습니다 & 서비스를하고있다.

+0

도중에 'Task.Factory.StartNew (async() => await Handle());을 단지'Handle()'으로 대체 할 수 있습니다. – Evk

+0

@Evk OmniSharp의 Visual 코드 편집기에서 경고를 건너 뛰었 기 때문에이 작업을 수행했습니다. 논리에 대해서는 동의합니다. 공장은 말이되지 않습니다. –

+0

당신은 의도를 명확히하고 그 경고를 제거하기 위해서'public static class TaskExtensions {public static void Forget (this Task task) {}}'와 같은 확장 메소드를 사용할 수 있습니다. (물론 태스크를 무시하는 것은 좋지 않습니다. 당신이 관찰하지 않을 예외를 던질 수 있습니다). – Evk