2. C# 비동기 프로그래밍 : async, await 이해
3. C# 비동기 프로그래밍 : Task의 연속 작업 (Continuations) 이해
이번 포스팅은 Task의 연속 작업에 대해 정리하였습니다.
비동기 프로그래밍의 중요한 방법 중 하나이며 복잡한 비동기를 쉽게 다루는데 도움을 줄 수 있는 개념입니다.
| Task 연속 작업(Continuations) 이해
Task 연속 작업은 Task가 끝난 뒤 바로 수행되는 작업을 말합니다.
이는 Task.ContiuneWith() 메서드를 통해 구현할 수 있습니다.
"ContuneWith" 이름에서 알 수 있듯이, 기존의 Task가 완료된 후에 "계속해서" 수행될 작업을 설정합니다.
예제) 팩토리얼 계산 후 출력하는 연속 작업
Task<int> firstTask = Task.Run(() => {
int result = 1;
for (int i = 1; i <= 10; i++)
{
result *= i;
}
return result;
});
Task secondTask = firstTask.ContinueWith(previousTask => {
// 첫 번째 Task의 결과를 사용하여 두 번째 Task 수행
Console.WriteLine("The factorial of 10 is " + previousTask.Result);
});
위 코드를 보시면 Task.Run을 사용하여 10의 팩토리얼을 계산하는 firstTask를 생성, 시작하고 있으며
그리고 firstTask가 완료된 후에 결과를 출력하는 secondTask를 생성하고 있습니다.
ContinueWith 메서드는 이전 Task(firstTask)의 결과를 인자로 받아 새로운 Task(secondTask)를 생성합니다.
이렇게 생성된 새로운 Task는 이전 Task가 완료된 후 실행됩니다.
연속 작업은 Task 스케줄러에 의해 관리되며, 기본적으로 이전 Task와 동일한 스레드에서 실행됩니다.
하지만 TaskCotinuationOptions를 사용하면 연속 작업의 스케줄링 방법을 변경할 수 있습니다.
예를 들어, TaskContinuationOptions.LongRunning 옵션을 사용하면
연속 작업이 별도의 스레드에서 실행되도록 할 수 있습니다.
예제) TaskContinuationOptions.LongRunning 옵션 구현
Task secondTask = firstTask.ContinueWith(previousTask => {
Console.WriteLine("The factorial of 10 is " + previousTask.Result);
}, TaskContinuationOptions.LongRunning);
| Task 연속 작업 응용 방법
연속 작업은 비동기 작업의 결과를 처리하거나, 여러 비동기 작업을 연쇄적으로 실행할 때 유용하게 사용됩니다.
예를 들어, 장비에서 데이터를 비동기적으로 읽은 후 그 결과를 처리하는 경우에 연속 작업을 사용할 수 있습니다.
예제) TCP/IP 통신과 RS232 통신을 통해 데이터를 받고 처리하는 코드
// TCP/IP 통신을 통해 장비에서 데이터를 받는 비동기 작업
Task<string> tcpIpDataTask = Task.Run(() => {
string data = ReceiveDataOverTcpIp(); // TCP/IP 통신을 통해 데이터를 받는 함수
return data;
});
// 받은 데이터를 처리하는 연속 작업
Task tcpIpProcessDataTask = tcpIpDataTask.ContinueWith(previousTask => {
string data = previousTask.Result;
ProcessData(data); // 데이터를 처리하는 함수
});
// RS232 통신을 통해 장비에서 데이터를 받는 비동기 작업
Task<string> rs232DataTask = Task.Run(() => {
string data = ReceiveDataOverRs232(); // RS232 통신을 통해 데이터를 받는 함수
return data;
});
// 받은 데이터를 처리하는 연속 작업
Task rs232ProcessDataTask = rs232DataTask.ContinueWith(previousTask => {
string data = previousTask.Result;
ProcessData(data); // 데이터를 처리하는 함수
});
위 코드는 제가 간단하게 TCP/IP 통신과 RS232 통신을 통해 장비에서 데이터를 비동기적으로 받고,
받은 데이터를 처리하는 연속 작업을 간단하게 구현해 봤습니다.
| Task 연속 작업 사용 시 주의점
하지만 ContinueWith 메서드를 사용할 때는 주의해야 할 점이 있습니다.
이 메서드는 이전 Task가 완료된 즉시 실행되므로, 이전 Task의 상태를 적절하게 처리하지 않으면
예외가 발생할 수 있습니다.
따라서 이전 Task의 상태를 확인하고 필요한 경우 예외 처리를 하는 것이 중요합니다.
예제) Task.ContinueWith 메서드의 예외처리
Task<int> firstTask = Task.Run(() => {
int result = 1;
for (int i = 1; i <= 10; i++)
{
result *= i;
}
return result;
});
Task secondTask = firstTask.ContinueWith(previousTask => {
if (previousTask.IsFaulted)
{
// 예외 발생 시 처리할 로직
Console.WriteLine("An error occurred: " + previousTask.Exception.Message);
}
else
{
Console.WriteLine("The factorial of 10 is " + previousTask.Result);
}
});
앞서 설명한 팩토리얼 계산 코드에서 예외가 발생했을 때 처리하는 방법에 대해 구현을 하였습니다.
만약 firstTask에서 예외가 발생하여 작업이 실패한 경우 (IsFaulted 상태), 예외 메시지를 출력합니다.
이렇게 예외 처리를 하여 오류를 방지하고 적절한 대응을 할 수 있습니다.
| 마무리
Task 연속 작업에 대해 정리하였습니다.
ContinueWith 메서드를 이용하면 비동기 작업의 결과를 효과적으로 이용하고 처리할 수 있습니다.
이를 이해하고 잘 활용한다면 더욱 비동기 프로그래밍을 효율적으로 할 수 있을 것 같습니다!
틀린 점이나 질문이 있으시면 댓글로 남겨주세요!
감사합니다 :)
'C#' 카테고리의 다른 글
C# 비동기 프로그래밍 : deadlock 문제와 해결 방법 (0) | 2023.11.23 |
---|---|
C# 비동기 프로그래밍 : Thread와 Task의 차이점 (0) | 2023.11.21 |
C# 비동기 프로그래밍 : async, await 이해 (0) | 2023.11.17 |
C# 비동기 프로그래밍 : Task 이해 (1) | 2023.11.16 |
C# 멀티캐스트 이벤트 이해 : 다중 이벤트 핸들러 관리 (0) | 2023.11.02 |