.NET Core对象池的应用:编程篇(3)

如果对象池的大小为当前机器处理器数量的2倍,那么我们倘若将对象的消费率提高,意味着池化的对象将无法满足消费需求,新的对象将持续被创建出来。为了验证我们的想法,我们按照如下的方式将每次迭代执行任务的数量加1。

class Program { static async Task Main() { var objectPool = new ServiceCollection().AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>() .BuildServiceProvider() .GetRequiredService<ObjectPoolProvider>() .Create(new FoobarPolicy()); var poolSize = Environment.ProcessorCount * 2; while (true) { while (true) { await Task.WhenAll(Enumerable.Range(1, poolSize + 1) .Select(_ => ExecuteAsync())); Console.WriteLine($"Last service: {FoobarService._latestId}"); } } … } }

再次运行改动后的程序,我们会在控制台上看到如下图所示的输出结果。由于每次迭代针对对象的需求量是17,但是对象池只能提供16个对象,所以每次迭代都必须额外创建一个新的对象。

.NET Core对象池的应用:编程篇

五、对象的释放

由于对象池容纳的对象数量是有限的,如果现有的所有对象已经被提取出来,它会提供一个新创建的对象。从另一方面讲,我们从对象池得到的对象在不需要的时候总是会还回去,但是对象池可能容不下那么多对象,它只能将其丢弃,被丢弃的对象将最终被GC回收。如果对象类型实现了IDisposable接口,在它不能回到对象池的情况下,它的Dispose方法应该被立即执行。

为了验证不能正常回归对象池的对象能否被及时释放,我们再次对演示的程序作相应的修改。我们让FoobarService类型实现IDisposable接口,并在实现的Dispose方法中将自身ID输出到控制台上。然后我们按照如下的方式以每次迭代并发量高于对象池大小的方式消费对象。

class Program { static async Task Main() { var objectPool = new ServiceCollection().AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>() .BuildServiceProvider() .GetRequiredService<ObjectPoolProvider>() .Create(new FoobarPolicy()); while (true) { Console.Write("Disposed services:"); await Task.WhenAll(Enumerable.Range(1, Environment.ProcessorCount * 2 + 3).Select(_ => ExecuteAsync())); Console.Write("\n"); } async Task ExecuteAsync() { var service = objectPool.Get(); try { await Task.Delay(1000); } finally { objectPool.Return(service); } } } } public class FoobarService: IDisposable { internal static int _latestId; public int Id { get; } private FoobarService() => Id = Interlocked.Increment(ref _latestId); public static FoobarService Create() => new FoobarService(); public void Dispose() => Console.Write($"{Id}; "); }

演示程序运行之后会在控制台上输出如下图所示的结果,可以看出对于每次迭代消费的19个对象,只有16个能够正常回归对象池,有三个将被丢弃并最终被GC回收。由于这样的对象将不能被复用,它的Dispose方法会被调用,我们定义其中的释放操作得以被及时执行。

.NET Core对象池的应用:编程篇

.NET Core对象池的应用:设计篇
.NET Core对象池的应用:扩展篇

到此这篇关于.NET Core对象池的应用:编程篇的文章就介绍到这了,更多相关.NET Core对象池的应用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysfdy.html