C#对象池模式

应用场景:高频对象的创建,导致内存攀升

using ObjectPoolDemo.Util;

namespace ObjectPoolDemo
{
    /*
     * 应用场景:高频对象的创建,导致内存攀升
     * 解决方案:使用对象池进行管理(创建&回收) 
     */
    public class Connection
    {
        public Guid Id { get; } = Guid.NewGuid();
        public bool IsActive { get; set; }
        
        public void Connect()
        {
            IsActive = true;
            Console.WriteLine($"{DateTime.Now} Sync Connection {Id} established.");
            Thread.Sleep(300);// 模拟同步连接操作
        }

        public void Disconnect()
        {
            IsActive = false;
            Console.WriteLine($"{DateTime.Now} Sync Connection {Id} closed.");
            Thread.Sleep(300);// 模拟同步断开操作
        }

        public async Task ConnectAsync()
        {
            IsActive = true;
            Console.WriteLine($"{DateTime.Now} Async Connection {Id} established.");
            await Task.Delay(300); // 模拟异步连接操作
        }

        public async Task DisconnectAsync()
        {
            IsActive = false;
            Console.WriteLine($"{DateTime.Now} Async Connection {Id} closed.");
            await Task.Delay(300); // 模拟异步断开操作
        }
    }

    class Program
    {  
        static void Main(string[] args)
        {
            //ObjectPolTest_Sync();

            ObjectPolTest_Async();

            Console.ReadKey();
        }

        static void ObjectPolTest_Sync()
        {
            // 创建对象池(同步)
            var pool = new ObjectPool<Connection>(
                objectGenerator: () => new Connection(), // 创建新对象的方法
                objectReset: conn => conn.Disconnect(),  // 重置对象的方法 
                maxSize: 10                               // 最大池大小 1000
            );

            // 模拟高频率对象获取和归还(同步)
            for (int i = 0; i < 1000; i++)
            {
                ThreadPool.QueueUserWorkItem(state =>
                {
                    var conn = pool.Get();
                    try
                    {
                        conn.Connect(); 
                    }
                    finally
                    {
                        pool.Return(conn);
                    }
                });
            }
        }

        static async void ObjectPolTest_Async()
        {
            // 创建对象池(异步)
            var pool = new ObjectPoolAsync<Connection>(
                objectGenerator: async () => new Connection(),
                objectReset: async conn => await conn.DisconnectAsync(),
                maxSize: 10
            );

            // 初始化对象池
            await pool.InitializeAsync();

            // 模拟高频率对象获取和归还(异步)
            for (int i = 0; i < 1000; i++)
            {
                Task.Run(async () =>
                {
                    var conn = await pool.GetAsync();
                    try
                    { 
                        await conn.ConnectAsync();
                    }
                    finally
                    {
                        await pool.ReturnAsync(conn);
                    }
                });
            }
        }
    }
}
using System.Collections.Concurrent;

namespace ObjectPoolDemo.Util
{
    /// <summary>
    /// 对象池
    /// </summary>
    public class ObjectPool<T> where T : class
    {
        private readonly ConcurrentBag<T> objects = new ConcurrentBag<T>();
        private readonly Func<T> objectGenerator;
        private readonly Action<T> objectReset;  
        public int maxSize;

        public ObjectPool(Func<T> objectGenerator, Action<T> objectReset = null, int maxSize = 1000)
        { 
            this.objectGenerator = objectGenerator;
            this.objectReset = objectReset;
            this.maxSize = maxSize;

            // 预创建初始对象
            for (int i = 0; i < maxSize; i++)
            {
                objects.Add(objectGenerator());
            }
        } 

        public T Get()
        {
            // 池不为空,返回对象
            if (objects.TryTake(out T item))
            {
                return item;
            }

            // 池已满,等待
            while (true)
            {
                if (objects.TryTake(out item))
                {
                    return item;
                }
                Thread.SpinWait(10); // 短暂等待避免CPU过度占用
            }
        }

        public void Return(T item)
        { 
            // 重置对象信息
            objectReset?.Invoke(item);

            objects.Add(item);
        } 
    }
}
using System.Collections.Concurrent;

namespace ObjectPoolDemo.Util
{
    /// <summary>
    /// 异步对象池
    /// </summary>
    public class ObjectPoolAsync<T> where T : class
    {
        private readonly ConcurrentBag<T> objects = new ConcurrentBag<T>();
        private readonly Func<ValueTask<T>> objectGenerator;
        private readonly Func<T, ValueTask> objectReset;
        private readonly int maxSize; 

        public ObjectPoolAsync(Func<ValueTask<T>> objectGenerator, Func<T, ValueTask> objectReset = null, int maxSize = 1000)
        {
            this.objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
            this.objectReset = objectReset;
            this.maxSize = maxSize; 
        }

        /// <summary>
        /// 异步初始化对象池
        /// </summary>
        public async Task InitializeAsync()
        {
            for (int i = 0; i < maxSize; i++)
            {
                var obj = await objectGenerator().ConfigureAwait(false);
                objects.Add(obj);
            }
        }

        /// <summary>
        /// 异步获取对象
        /// </summary>
        public async ValueTask<T> GetAsync(CancellationToken cancellationToken = default)
        { 
            // 池不为空,返回对象
            if (objects.TryTake(out T item))
            { 
                return item;
            }

            // 池已满,等待
            while (!objects.TryTake(out item))
            {
                await Task.Delay(10, cancellationToken).ConfigureAwait(false);
            } 

            return item;
        }

        /// <summary>
        /// 异步归还对象
        /// </summary>
        public async ValueTask ReturnAsync(T item)
        {
            await objectReset(item).ConfigureAwait(false);
            objects.Add(item);
        }
    }
}

 

posted @ 2025-08-29 11:28  CHHC  阅读(10)  评论(0)    收藏  举报