Programming/.NET

System.Threading.EventWaitHandle을 사용하면 스레드간 통신을 통해 작업을 동기화 할 수 있습니다.

 

static void Main(string[] args)
{
    EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset);

    Thread t1 = new Thread(myThread);
    t1.IsBackground = true;
    t1.Start(ewh);

    ewh.WaitOne();
    ewh.Reset();

    Thread t2 = new Thread(myThread);
    t2.IsBackground = true;
    t2.Start(ewh);

    ewh.WaitOne();

    Console.Read();
}

static void myThread(object o)
{
    Console.WriteLine("thread 실행");

    Thread.Sleep(10000);

    ((EventWaitHandle)o).Set();
}

 

예제에서는 2개의 스레드를 생성하는데 이때 EventWaitHandle을 사용하여 스레드를 시작합니다. EventWaitHandle의 인스턴스를 생성할때는 2개의 인자를 전달할 수 있는데 첫번째인자는 개체상태를 Signal 로 할것인지 Non-Signal 할것인지를 결정합니다. false로 지정하면 개체는 Non-Signal이 됩니다.

 

예제를 보시면 개체가 WaitOne() 메서드를 호출하는데 만약 이때 개체의 상태가 Signal이면 곧바로 처리를 계속할 수 있도록 제어를 반환하지만 Non-Signal상태라면 개체가 Singal이 될때까지 계속 대기상태에 머무르게 됩니다. myThread메서드에서는 마지막에 전달된 EventWaitHandle개체에 Set() 메서드를 호출하는 부분이 있는데 바로 이때 개체의 상태는 Signal로 전환됩니다. 그런 후 개체는 WaitOne() 메서드를 호출한 시점부터 제어가 반환되어 그 이후의 처리를 계속 진행하는 것입니다.

 

EventWaitHandle의 개체를 생성할때 두번째 인자에서 ManualReset을 지정했는데 이렇게 하면 Set() 메서드가 호출되 개체의 상태가 Signal로 바뀌었을때 다시 Non-Signal로 상태가 변하지 않습니다. 상태를 바꾸려면 임의로 Reset() 메서드를 호출해야 합니다. 반면 AutoReset으로 하면 Signal로 상태가 변한 후 다시 자동으로 Non-Signal 상태로 바뀌게 됩니다. 예제에서 첫번째 WaitOne() 메서드를 호출할때 뒤이어 Reset() 메서드를 호출해 개체의 상태를 Non-Signal로 바꾸고 있는데 이렇게 하지 않으면 두번째 WaitOne() 에서 대기상태에 머무르지 않고 바로 처리가 종료될것입니다. 상태전환을 ManualReset으로 했기 때문에 한번 바뀐 EventWaitHandle의 상태가 계속 유지되는 것입니다. 만약 이것을 AutoReset으로 했다면 임의로 Reset()을 호출하는 부분은 생략이 가능할 것입니다.

'Programming > .NET' 카테고리의 다른 글

[C#] Stack / Queue  (0) 2018.02.13
[ASP.NET MVC] 프로젝트 폴더 구성  (0) 2018.02.09
[C#] EventWaitHandle  (0) 2018.01.16
[ASP.NET MVC] 번들(Bundle)  (0) 2018.01.02
[C#] nameof  (0) 2017.12.27
[ASP.NET MVC] AJAX  (0) 2017.12.22
0 0