2026년 6월 12일 금요일

닷넷의 시그널링 기법

async  await Task가 나오고나서 개발 패러다임이 많이 바뀌었다.

오늘 그중에서 시그널링 기법에 대해 말하려한다.

예를 들어  이런 상황이 발생할수 있다.
단순히 int를 리턴하는 함수 F1이 있다..
이 함수를 호출원에서 await해서 기다림으로 인해서 
다른 쓰레드 처리나 이런것에 방해를 주지 않는다..

그런데 그 값을 가지고 오는 주체가 F1내부가 아니라
F2에서 값을 가져와야 하는 경우가 있다.

이경우 F1은 await으로 결과를 기다리고 있는것을 풀어줘야한다.
이처리가 구현하기 나름인데..


[구방식 (메뉴얼리셋 이용)]

private int myResult = 0;
private ManualResetEvent myEvent = new ManualResetEvent(false);
private async Task<int> F1()
{
        // 사전작업..
        myEvent.Reset();
        awiat Task.Run(() => myEvent.WaitOne(TimeSpan.MaxValue));
        return myResult;
}
private void F2(int result)
{
      myResult = result;
      myEvent.Set();
}


[신규방식 (TaskCompletionSource 이용)]

private TaskCompletionSource<int>? _popupResultTcs;
private Task<int> F1()
{
       //사전작업..
       _popupResultTcs = new TaskCompletionSource<int>();       
        return _popupResultTcs.Task;
}
private void F2(int resultCode)
{       
       _popupResultTcs?.TrySetResult(resultCode);
}



[호출원에서 사용]

이제 호출 원에서는 그냥 
int res = await F1();

이라고 처리하면 된다.. 
차이점은 구방식은 쓰레드 하나를 통으로 점유하게 되고
신규방식은 int를 리턴할것을 약속만 하는것이므로 자원점유를 하지 않는다.
그리고 실제 SetResult 시점에 결과가 박히게 됨



ㅇㅇ 좋은 기법




댓글 없음:

댓글 쓰기