별도의 스레드에서 일부 서비스를 시작하는 콘솔 애플리케이션을 고려하십시오. 사용자가 Ctrl + C를 눌러 종료 할 때까지 기다리기만하면됩니다.
다음 중이 작업을 수행하는 더 좋은 방법은 무엇입니까?
static ManualResetEvent _quitEvent = new ManualResetEvent(false);
static void Main() {
Console.CancelKeyPress += (sender, eArgs) => {
_quitEvent.Set();
eArgs.Cancel = true;
};
// kick off asynchronous stuff
_quitEvent.WaitOne();
// cleanup/shutdown and quit
}
또는 Thread.Sleep (1) 사용 :
static bool _quitFlag = false;
static void Main() {
Console.CancelKeyPress += delegate {
_quitFlag = true;
};
// kick off asynchronous stuff
while (!_quitFlag) {
Thread.Sleep(1);
}
// cleanup/shutdown and quit
}
답변
특히 코드에서 변수를 다시 확인하도록 할 때 항상 while 루프를 사용하지 않으려 고합니다. CPU 리소스를 낭비하고 프로그램 속도를 늦 춥니 다.
나는 확실히 첫 번째를 말할 것입니다.
답변
또는 더 간단한 솔루션은 다음과 같습니다.
Console.ReadLine();
답변
그렇게 할 수 있습니다 (그리고 CancelKeyPress
이벤트 핸들러를 제거하십시오 ).
while(!_quitFlag)
{
var keyInfo = Console.ReadKey();
_quitFlag = keyInfo.Key == ConsoleKey.C
&& keyInfo.Modifiers == ConsoleModifiers.Control;
}
그게 더 좋은지는 모르겠지만 Thread.Sleep
루프에서 호출한다는 생각이 마음에 들지 않습니다 . 사용자 입력을 차단하는 것이 더 깔끔하다고 생각합니다.
답변
나는 Application.Run을 사용하는 것을 선호합니다.
static void Main(string[] args) {
//Do your stuff here
System.Windows.Forms.Application.Run();
//Cleanup/Before Quit
}
문서에서 :
양식없이 현재 스레드에서 표준 응용 프로그램 메시지 루프 실행을 시작합니다.
답변
필요한 것보다 더 어렵게 만드는 것 같습니다. Join
중지하라는 신호를 보낸 후 스레드가 아닌 이유는 무엇 입니까?
class Program
{
static void Main(string[] args)
{
Worker worker = new Worker();
Thread t = new Thread(worker.DoWork);
t.IsBackground = true;
t.Start();
while (true)
{
var keyInfo = Console.ReadKey();
if (keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers == ConsoleModifiers.Control)
{
worker.KeepGoing = false;
break;
}
}
t.Join();
}
}
class Worker
{
public bool KeepGoing { get; set; }
public Worker()
{
KeepGoing = true;
}
public void DoWork()
{
while (KeepGoing)
{
Console.WriteLine("Ding");
Thread.Sleep(200);
}
}
}
답변
취소 토큰을 기반으로 스레드 / 프로그램을 차단할 수도 있습니다.
token.WaitHandle.WaitOne();
WaitHandle은 토큰이 취소되면 신호를 보냅니다.
Microsoft.Azure.WebJobs.JobHost에서이 기술을 사용하는 것을 보았습니다. 여기서 토큰은 WebJobsShutdownWatcher (작업을 종료하는 파일 감시자)의 취소 토큰 소스에서 가져옵니다.
이것은 프로그램이 언제 종료 될 수 있는지에 대한 제어를 제공합니다.
답변
첫 번째 두 개 중 하나가 더 좋습니다
_quitEvent.WaitOne();
두 번째에서 스레드는 매 1 밀리 초마다 깨어나 기 때문에 비용이 많이 드는 OS 인터럽트로 전환됩니다.