C#/C#이야기

[C#] EventWaitHandle로 TimeOut기능 만들기

반나무 2022. 1. 23. 16:43

EventWaitHandle

두가지 상태를 가지며 Set을 통해 Non-Signal -> Signal, Reset을 통해 Signal -> Non-Signal로 상태 변경이 가능하다.

  • Non-Signal : 제어를 반환하지 않음(잠금)
  • Signal : 제어를 반환(열림)
private EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset);

 

AutoResetEvent

EventWaitHandle을 사용하지 않고 따로 생성도 가능하다.

Set하면 대기중인 스레드 중 첫번째로 대기 시작한 쓰레드 하나를 진행하시킨다.

private static AutoResetEvent autoEvt = new AutoResetEvent(false);

ManualResetEvent

EventWaitHandle을 사용하지 않고 따로 생성도 가능하다.

private static ManualResetEvent manualEvt = new ManualResetEvent(false);

WaitOne(int n);

n초간 Set을 기다린다. 빈칸으로 두면 무한대기한다.

Set을 만나면 true가 return된다. Set을 만나지못하면 false가 return된다.

 

Set();

Set하는 메소드

 

Reset();

Reset하는 메소드

 

AutoResetEvent와 ManualResetEvent의 차이점

1. WaitOne의 대기상태가 Set으로 인해 풀린 이후, 곧바로 Reset을 수동으로 하느냐, 자동으로 하느냐의 차이가 있다.

2. AutoResetEvent는 스레드 하나만 진행된다, ManualResetEvent는 모든 스레드를 진행되게 할 수있다.

 


TimeOut기능 만들기

1. Field

우선 Field에 WorkerThread와 TimeoutThread 두개를 만들어준다.

// Thread
private Thread _workerThread;
private Thread _timeoutThread;

// Start시 Running 판단 트리거
private bool _isRunning = false;

 

2. StartButton 메소드

StartButton클릭시 작동하는 thread를 생성한다.

public void Start()
{
    _isRunning = true;

    _workerThread = new Thread(new ThreadStart(Callback))
    {
        Name = "WorkThread",
        IsBackground = true
    };
    _workerThread.Start();

    _timeoutThread = new Thread(new ThreadStart(TimeOut))
    {
        Name = "TimeOutThread",
        IsBackground = true
    };
    _timeoutThread.Start();
}

3. Callback Method

해당 스레드는 Text를 바인딩해 +1 해준다.

public void Callback()
{
    while(_isRunning)
    {
        for (int i = 0; i < 1000; i++)
        {
        	// 정상작동중일때 ewh.Set해서 진입
            ewh.Set();
            Text = $"{i}";
        }
    }
}

4. TimeOut Method

해당 스레드는 3초안에 Set이 오지않으면 타임아웃메세지가 출력된다.

public void TimeOut()
{
	// 정상 작동이라면 true -> !만나서 false로 아무 작동 안함
    // 비정상 작동이라면 false -> !만나서 true로 타임아웃 작동
    if (!ewh.WaitOne(3000))
    {
    	Stop();
        MessageBox.Show("타임아웃!!");
    }
}

 

5. 3초 대기 동안 Set이 오지 않을시 TimeOut작동되는 모습

반응형