나는 자체 스레드에서 실행되는 프로세스를 가지고 있으며 차단하지 않고 시작/중지 할 수 있습니다. 이것은 결국 Windows 서비스로 들어갈 것이지만, 지금까지 콘솔 앱에서이 기능을 설정하고 있습니다.while 루프 대신 세마포어 사용. 이게 좋은 일입니까 나쁜 일입니까?
Start() 호출 후 Ctrl-C를 누를 때까지 주 프로그램 스레드를 차단하고 싶습니다. 나는이 일 것이라는 점을 알고있다 :
public static void Main(string[] args)
{
bool keepGoing = true;
var service = new Service();
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
keepGoing = false; // Break the while loop below
};
service.Start();
while(keepGoing)
{
Thread.Sleep(100); // 100 is arbitrary
}
}
그러나, 나는 플래그와 임의의 수면 값이 귀찮은 찾을 수 있습니다. 나는 while 루프에서 CPU 비용이 거의 0이라는 것을 알고 있지만, Ctrl-C 핸들러가 끝나자 마자 "하드"블록을 릴리스하고 싶습니다. 나는 익명의 Ctrl-C 처리기가 완료 될 때까지 차단하기 위해 세마포어를 사용하여 아래를 고안했다 :
public static void Main(string[] args)
{
var service = new Service();
var s = new Semaphore(1, 1);
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
s.Release(); // This will allow the program to conclude below
};
service.Start();
s.WaitOne(); // This will not block
s.WaitOne(); // This will block w/o CPU usage until the sempahore is released
}
이것은 잘못된 설계인가? 과잉인가요? 위험한가요?
편집 : 2
AppDomain.CurrentDomain.UnhandledException += delegate {
service.Stop();
s.Release();
};
편집 : 다음과 같이 나 또한 AppDomain.CurrentDomain.UnhandledException를 연결
는는 그 중요한
내가주의해야한다입니다 출구에서 Stop()
메서드가 호출됩니다. @Adam Ralph는 하이브리드 콘솔/서비스에 대한 완벽한 패턴을 가지고 있지만 Q에 대답 할 때이 정보가 없습니다.
while 루프를 피할 수만 있다면 그럴만 한 가치가 있다고 말합니다. – ChaosPandion
프로토 타이핑을 위해서는 후자가 많이 개선되었습니다. 프로덕션 응용 프로그램에서 나는 전체 "CTRL + C"중단 생각을 피할 것입니다. 대신 스레드를 죽이기 위해 신호를 사용하십시오. 신호가'Set()'인 방식은 관련된 다른 레이어에 달려 있습니다. 서비스를 설계 할 때이를 명심하십시오. 'Set()'을 호출 할 수있는 메소드와 같은 수단을 추가하십시오. –
@ P.Brian.Mackey :이 프로그램은 프로덕션 애플리케이션이 아니지만 * * 인 경우 비대화 형 콘솔 앱에서 Ctrl-C를 정상적으로 처리하는 것이 현명하지 않습니까? 그대로, Ctrl-C는 종료하기 전에 정리할 기회없이 단순히 프로그램을 종료합니다. 궁극적으로, 나는 단순히 "while (flag) Thread.Sleep (...)"옵션에 대한 세마포어 솔루션인지 궁금합니다. –