프로그래밍/.NET2013. 2. 5. 16:35

스레드 풀은 백그라운드에서 여러 가지 작업을 수행하는데 사용할 수 있는 스레드의 컬렉션입니다. 스레드 풀을 사용하면 기본 스레드에서 다른 작업을 비동기적으로 수행할 수 있습니다.

스레드 풀에는 일반적으로 스레드의 최대 수가 지정되어 있습니다. 모든 스레드에서 작업을 수행 중이면 다른 작업은 사용 가능한 스레드가 생길 때까지 큐에 배치됩니다. 가능한 스레드가 생기면 자동으로 큐에 배치되어 있던 스레드가 실행이 됩니다.


예제 : MSDN

program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadPool_Sample
{
    public class Fibonacci
    {
        private int _n;
        private int _fibOfN;
        private ManualResetEvent _doneEvent;

        public int N { get { return _n; } }
        public int FibOfN { get { return _fibOfN; } }

        // Constructor. 
        public Fibonacci(int n, ManualResetEvent doneEvent)
        {
            _n = n;
            _doneEvent = doneEvent;
        }

        // Wrapper method for use with thread pool. 
        public void ThreadPoolCallback(Object threadContext)
        {
            int threadIndex = (int)threadContext;
            Console.WriteLine("thread {0} started...", threadIndex);
            _fibOfN = Calculate(_n);
            Console.WriteLine("thread {0} result calculated...", threadIndex);

            // 스레드가 완료하면 현재 스레드가 완료되었다고 신호를 줍니다.
           _doneEvent.Set();
        }

        // Recursive method that calculates the Nth Fibonacci number. 
        public int Calculate(int n)
        {
            if (n <= 1)
            {
                return n;
            }

            return Calculate(n - 1) + Calculate(n - 2);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            const int FibonacciCalculations = 10;

            // One event is used for each Fibonacci object.
            ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
            Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
            Random r = new Random();

            // Configure and start threads using ThreadPool.
            Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
            for (int i = 0; i < FibonacciCalculations; i++)
            {
                doneEvents[i] = new ManualResetEvent(false);
                Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);
                fibArray[i] = f;
                
                // 스레드 풀에 수행할 작업을 입력합니다.
                ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
            }

            // 스레드 풀에 있는 스레드 작업이 완료 될때까지 대기합니다.
            // 모든 스레드가 완료 되었다는 신호를 받으면 결과값을 보여줍니다.
            WaitHandle.WaitAll(doneEvents);
            Console.WriteLine("All calculations are complete.");

            // Display the results. 
            for (int i = 0; i < FibonacciCalculations; i++)
            {
                Fibonacci f = fibArray[i];
                Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
            }

            Console.ReadLine();
        }
    }
}



만약, 스레드가 완료될때까지 기다리지 않는다면 어떻게 될까요?

            // 스레드 풀에 있는 스레드 작업이 완료 될때까지 대기합니다.
            // 모든 스레드가 완료 되었다는 신호를 받으면 결과값을 보여줍니다.
            //WaitHandle.WaitAll(doneEvents);
            Console.WriteLine("All calculations are complete.");

            // Display the results. 
            for (int i = 0; i < FibonacciCalculations; i++)
            {
                Fibonacci f = fibArray[i];
                Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
            }

            Console.ReadLine();

계산이 끝나기 전에 결과값을 출력을 해서 값이 없습니다.

ThredPool을 쓰실려면 EventWaitHandle 클래스를 잘 활용해야 원하는 값을 얻으실 수가 있을 것 같습니다.






Posted by 건깡