C#, .NET 프로그램에 사용할 수 있는 라이브러리 및 언어 기능을 사용하면 동시성(Concurrency) 구현을 쉽게 할 수 있다. 이전 강좌에서 C++ 예제로 Concurrent computing에 대한 개념1을 설명했다. 추가로 동시성 개요2를 다시 정리해 보면 다음과 같다.
여기에 사용한 예제3는 gavilanch3(Youtube) - Introduction to Concurrency in C#, 강좌를 참고하였다.
using System.Diagnostics;
var stopWatch = new Stopwatch();
var names = new List<string>() { "홍길동", "홍길서", "홍길남", "홍길북" };
Console.WriteLine("Default Start...(8초)");
stopWatch.Start();
foreach (var name in names)
{
await Method1(name);
await Method2(name);
await Method3(name);
await Method4(name);
}
stopWatch.Stop();
WriteTime(stopWatch.Elapsed.Seconds, ConsoleColor.Red);
Concurrent computing is a form of computing in which several computations are executed concurrently—during overlapping time periods—instead of sequentially—with one completing before the next starts1. 어떠한 프로그래밍 로직이 요청한 결과를 순차적으로 처리하는 것이 아닌 여러 곳의 요청을 동시에 처리하는 것을 말한다.
Concurrency는 Parallelism의 난해함을 풀어낸 방법2인데 대표적인 것이 Coroutine(C#, Unity)이다. Rust 프로그래밍에서 Concurrency 예제3와 Go 프로그래밍에서 Concurrency 예제4는 과거 포스팅한 글에서 볼 수 있다. 이번 예제는 Qt(C++)에서 Concurrency를 구현하는 간단한 예제를 VoidRealms5강좌를 통해 소개하였다.
cmake_minimum_required(VERSION 3.14)
project(QtExam LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core
Concurrent REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core
Concurrent REQUIRED)
add_executable(QtExam
main.cpp
)
target_link_libraries(QtExam Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Concurrent)
#set_target_properties(QtExam PROPERTIES WIN32_EXECUTABLE TRUE)
Delegate(델리게이트, 대리자)는 C#에서 매우 중요한 개념이다. Delegate는 CLI(Common Language Infrastructure)에서 사용하는 Type-safe function pointer의 한 형태1라고 설명할 수 있다.
Method를 참조하여 호출하기에 콜백 및 이벤트 리스너2를 구현하는 데 사용한다. C++의 함수 포인터3와 같은 개념이라고 보면 된다. 단순하게 설명하면 int, string 타입처럼 함수를 변수처럼 선언하거나 함수의 파라미터로 활용4할 수 있게 해주는 것이다.
아래의 코드(소스)는 델리게이트, 함수포인터의 개념을 이해하고 이를 활용하는 예제이다. Delegate의 형태에는 Action, Func, Predicate5가 있다.
// Lambda와 함께 LINQ를 사용할 수 있는 이유 : Delegate (Action, Func, Predicate)
List<int> list = new() { 2, 3, 4, 5, 6, 7 };
list.Where(x => x > 5).ToList().ForEach(Console.WriteLine);