방프리
24.05.27 C# 동시성 프로그래밍 (스케줄링) 본문
1. 스레드 풀에 작업 스케줄링
Task.Run을 사용하여 작업을 실행시킨다. 여러 기능이 있으나 Task.Run을 사용하는 것이 유지보수나 변경에 쉽다.
Task<int> task = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(2));
return 13;
});
2. 작업 스케줄러를 사용해서 코드 실행
TaskScheduler 중 TaskScheduler.Default는 작업을 스레드 풀의 큐에 넣는다. Task.Run, 병렬 처리, 데이터 흐름 코드는 모두 TaskScheduler.Default를 사용한다. TaskScheduler.FromCurrentSynchronizationContext를 사용해서 컨텍스트를 저장해놓고 나중에 다시 이 컨텍스트에 작업을 스케줄링할 수 있다.
이외에 ConcurrentExclusiveSchedulerPair라는 형식이 있는데 ExclusiveScheduler에 실행 중인 작업이 없을 때 여러 작업을 동시에 실행할 수 있는 스케줄러이다. 하지만 TaskScheduler는 플랫폼에 종속되어 사용될 수 있으니 가급적이면 사용하지 않는 것이 좋다.
3. 병렬 코드의 스케줄링
TaskScheduler 인스턴스를 생성한 후 Parallel 메서드에 전달할 옵션에 포함할 수 있다.
PLINQ에는 전달할 방법은 없다.
void RotateMatrices(IEnumerable<IEnumerable<Matrix>> collections, float degrees)
{
var schedulerPair = new ConcurrentExclusiveSchedulerPair(
TaskScheduler.Default, maxConcurrencyLevel: 8);
TaskScheduler scheduler = schedulerPair.ConcurrentScheduler;
ParallelOptions options = new ParallelOptions { TaskScheduler = scheduler };
Parallel.ForEach(collections, options
matrices => Parallel.ForEach(matrices, options,
matrix => matrix.Rotate(degrees));
}
4. 스케줄러로 데이터 흐름 동기화
TaskScheduler 인스턴스를 만들고 나면 데이터 흐름 블록에 전달할 옵션에 포함할 수 있다.
var options = new ExcutionDataflowBlockOptions
{
TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(),
};
var multiplyBlock = new TransformBlock<int, int>(item => item * 2);
var displayBlock = new ActionBlock<int>(
result => ListBox.Items.Add(result), options);
multiplyBlock.LinkTo(displayBlock);
'C# > 동시성 처리' 카테고리의 다른 글
24.05.29 C# 동시성 프로그래밍 (다양한 동시성 상황) (1) | 2024.05.29 |
---|---|
24.05.26 C# 동시성 프로그래밍 (동기화) (0) | 2024.05.26 |
24.05.24 C# 동시성 프로그래밍 (함수형 친화적 OOP) (0) | 2024.05.24 |
24.05.22 C# 동시성 프로그래밍 (취소) (0) | 2024.05.22 |
24.05.21 C# 동시성 프로그래밍 (컬렉션) (0) | 2024.05.21 |