CPU는 여러 개의 Core로 구성되어 있고 각 Core 단위로 동시에 연산을 처리할 수 있습니다. C#에서 CPU를 최대한 이용하기 위해서 Parallel API를 이용한 코드를 정리합니다.
Task.Factory.StartNew(() => { Parallel.ForEach(addressData, new ParallelOptions { MaxDegreeOfParallelism = cntCores }, (task) => { int iAddress = task.Index; string Address = task.Address; /* 시간이 많이 걸리는 연산을 처리하는 스코프 */ Invoke(new Action(() => { // UI 처리가 가능한 스코프 })); //Application.DoEvents(); -> 더 이상 필요치 않음 } ); });
중요한 점은 Parallel에서 만들어진 스레드는 Main 스레드에서 구동되면 안됩니다. 그래서 Task.Factory.StartNew를 통해 별도의 스레드를 하나 만들고.. 만들어진 스레드에서 Parallel의 스레드를 구동하게 합니다. Task.Factory.StartNew를 사용한 이유는 스레드를 간단하게 만들 수 있기 때문으로 다른 스레드를 만드는 코드도 유효합니다. addressData는 스레드를 통해 처리해야할 데이터가 담긴 컨테이너입니다. 예를 들어 다음과 같습니다.
List<ADDRESS_DATA> addressData = new List<ADDRESS_DATA>();
ADDRESS_DATA는 다음과 같구요. (올바른 캡슐화를 적용하지 않은 코드입니다)
private class ADDRESS_DATA { public int Index; public String Address; public ADDRESS_DATA(int Index, String Address) { this.Index = Index; this.Address = Address; } }
Paralleld의 ForEach 매서드에서 task를 통해 ADDRESS_DATA의 필드값에 접근할 수 있습니다. 그리고 cntCores는 CPU의 코어 수인데, 동시에 실행할 수 있는 스레드의 개수로 지정하기 적당한 값입니다. 다음처럼 얻을 수 있습니다.
int cntCores = Environment.ProcessorCount;