오늘 그중에서 시그널링 기법에 대해 말하려한다.
예를 들어 이런 상황이 발생할수 있다.
단순히 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 시점에 결과가 박히게 됨
그리고 실제 SetResult 시점에 결과가 박히게 됨
ㅇㅇ 좋은 기법
댓글 없음:
댓글 쓰기