本示例演示如何使用并发包来实现对象池。 在需要某个类的多个实例并且创建或销毁该类的成本很高的情况下,对象池可以改进应用程序性能。 客户端程序请求新对象时,对象池先尝试提供一个已创建并返回到该池的对象。 仅在没有可用对象时,才会创建一个新对象。
ConcurrentBag<T> 用于存储对象,因为它支持快速插入和删除,特别是在同一线程既添加又删除项时。 本示例可进一步扩充为以包数据结构实现的 IProducerConsumerCollection<T> 为依据生成,就像 ConcurrentQueue<T> 和 ConcurrentStack<T> 一样。
using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace ObjectPoolExample { public class ObjectPool<T> { private ConcurrentBag<T> _objects; private Func<T> _objectGenerator; public ObjectPool(Func<T> objectGenerator) { if (objectGenerator == null) throw new ArgumentNullException("objectGenerator"); _objects = new ConcurrentBag<T>(); _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<MyClass> pool = new ObjectPool<MyClass>(() => 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(); } } }
相关推荐
c# 线程池的高级应用,值不值的一看,就看你了,vs2005代码齐全下载即可运行。
这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合...
这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合...
这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合...
Task task = BlockingCollectionUtil.AddTakeBlockingCollectionAsync(); Task.WaitAny(task); BlockingCollectionUtil.TryTakeBlockingCollection(); ConcurrentBagUtil.Test(); ConcurrentDictionaryUtil....
c#官方线程安全集合源码,concurrentBag concurrentqueue,concurrentset,concurrentDictionary,concurrentSet等