ConcurrentBag 을 사용 하여 대상 풀 을 만 듭 니 다.

3578 단어
더 읽 기
이 예제 에 서 는 대상 풀 을 어떻게 사용 하 는 지 보 여 줍 니 다. 특정한 종류의 여러 인 스 턴 스 가 필요 하고 이런 종류의 비용 이 높 은 상황 에서 대상 풀 은 응용 프로그램의 성능 을 개선 할 수 있 습 니 다. 클 라 이언 트 프로그램 이 새 대상 을 요청 할 때 대상 풀 은 먼저 만 들 고 이 풀 로 돌아 가 는 대상 을 제공 하려 고 시도 합 니 다. 사용 가능 한 대상 이 없 을 때 만 새 대상 을 만 듭 니 다.
ConcurrentBag 저장 대상 에 사용 합 니 다. 빠 른 삽입 과 삭 제 를 지원 하기 때 문 입 니 다. 특히 같은 스 레 드 에서 항목 을 추가 하고 삭제 할 때. 본 예 는 패키지 데이터 구조 로 이 루어 진 IProducerConsumerCollection 근거 로 생 성 하 다 ConcurrentQueue 화해시키다 ConcurrentStack 같다
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;


namespace ObjectPoolExample
{
    public class ObjectPool
    {
        private ConcurrentBag _objects;
        private Func _objectGenerator;

        public ObjectPool(Func objectGenerator)
        {
            if (objectGenerator == null) throw new ArgumentNullException("objectGenerator");
            _objects = new ConcurrentBag();
            _objectGenerator = objectGenerator;
        }

        public T GetObject()
        {
            T item;
            if (_objects.TryTake(out item)) return item;
            return _objectGenerator();
        }

        public void PutObject(T item)
        {
            _objects.Add(item);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            // Create an opportunity for the user to cancel.
            Task.Run(() =>
            {
                if (Console.ReadKey().KeyChar == 'c' || Console.ReadKey().KeyChar == 'C')
                    cts.Cancel();
            });

            ObjectPool pool = new ObjectPool(() => new MyClass());

            // Create a high demand for MyClass objects.
            Parallel.For(0, 1000000, (i, loopState) =>
            {
                MyClass mc = pool.GetObject();
                Console.CursorLeft = 0;
                // This is the bottleneck in our application. All threads in this loop
                // must serialize their access to the static Console class.
                Console.WriteLine("{0:####.####}", mc.GetValue(i));

                pool.PutObject(mc);
                if (cts.Token.IsCancellationRequested)
                    loopState.Stop();

            });
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            cts.Dispose();
        }

    }

    // A toy class that requires some resources to create.
    // You can experiment here to measure the performance of the
    // object pool vs. ordinary instantiation.
    class MyClass
    {
        public int[] Nums { get; set; }
        public double GetValue(long i)
        {
            return Math.Sqrt(Nums[i]);
        }
        public MyClass()
        {
            Nums = new int[1000000];
            Random rand = new Random();
            for (int i = 0; i < Nums.Length; i++)
                Nums[i] = rand.Next();
        }
    }
}

좋은 웹페이지 즐겨찾기