亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

.NET?Core?中對象池?Object?Pool的使用

 更新時間:2021年11月22日 12:52:32   作者:494324190  
這篇文章主要介紹了?.NET?Core?中對象池?Object?Pool的使用,對象池簡單來說就是一種為對象提供可復(fù)用能力的軟件設(shè)計(jì)思路,對象池最常用的場景是游戲設(shè)計(jì),因?yàn)樵谟螒蛑写罅看嬖谥蓮?fù)用的對象,源源不斷的子彈出現(xiàn)并不是循環(huán)再生的,下面一起進(jìn)入文章了解具體內(nèi)容吧

一、什么是對象池

對象池簡單來說就是一種為對象提供可復(fù)用能力的軟件設(shè)計(jì)思路。我們常說有借有還,再借不難,而對象池就是通過借和還這樣兩個動作來保證對象可以被重復(fù)使用,從而節(jié)省頻繁創(chuàng)建對象的性能開銷。對象池最常用的場景是游戲設(shè)計(jì),因?yàn)樵谟螒蛑写罅看嬖谥蓮?fù)用的對象,源源不斷的子彈出現(xiàn)并不是循環(huán)再生的。在數(shù)據(jù)庫中存在著被稱為連接池的東西,每當(dāng)出現(xiàn)數(shù)據(jù)庫無法連接的情況時,經(jīng)驗(yàn)豐富的開發(fā)人員往往會先檢查連接池是否滿了,這其實(shí)就是對象池模式在特定領(lǐng)域的具體實(shí)現(xiàn)。因此對象池本質(zhì)上就是負(fù)責(zé)一組對象創(chuàng)建和銷毀的容器。 對象池最大的優(yōu)勢是可以自主地管理池子內(nèi)的每個對象,決定它們是需要被回收還是可以重復(fù)使用。我們都知道創(chuàng)建一個新對象需要消耗一定的系統(tǒng)資源,一旦這些對象可以重復(fù)地使用就可以節(jié)省系統(tǒng)資源開銷,這對提高系統(tǒng)性能會非常有幫助。下面的代碼實(shí)微軟官方文檔實(shí)現(xiàn)的一個簡單的對象池:


public class ObjectPool<T> : IObjectPool<T>

{

	private Func<T> _instanceFactory;

	private ConcurrentBag<T> _instanceItems;

	public ObjectPool(Func<T> instanceFactory)

	{

		_instanceFactory = instanceFactory ?? 

		throw new ArgumentNullException(nameof(instanceFactory));

		_instanceItems = new ConcurrentBag<T>();

	}

	public T Get()

	{

		T item;

		if (_instanceItems.TryTake(out item)) return item;

		return _instanceFactory();

	}

	public void Return(T item)

	{

		_instanceItems.Add(item);

	}

}

二、.NET Core 中的對象池

.NET Core 中微軟已經(jīng)為我們提供了對象池的實(shí)現(xiàn),即Microsoft.Extensions.ObjectPool。它主要提供了三個核心的組件,分別是ObjectPoolObjectPoolProviderIPooledObjectPolicy。ObjectPool是一個抽象類,對外提供了Get和Return兩個方法,這就是所謂的有借有還。ObjectPoolProvider同樣是一個抽象類,它的職責(zé)就是創(chuàng)建ObjectPool,它提供了兩個Create方法,兩者的區(qū)別是無參數(shù)版本本質(zhì)上使用的是DefaultPooledObjectPolicy。它和DefaultObjectPool、DefaultObjectPoolProvider都是微軟提供的默認(rèn)實(shí)現(xiàn),IPooledObjectPolicy可以為不同的對象池定義不同的策略,來決定對象如何借、是否可以還。DefaultObjectPool內(nèi)部使用ObjectWrapper[]來管理對象,ObjectWrapper[]的大小等于 maximumRetained-1,默認(rèn)情況下maximumRetained等于Environment.ProcessorCount * 2,這里主要用到了Interlocked.CompareExchange()方法,

具體代碼如下:

public override T Get()

{

  var item = _firstItem;

  if (item == null || Interlocked.CompareExchange(ref _firstItem, null, item) != item)

  {

    var items = _items;

    for (var i = 0; i < items.Length; i++)

    {

      item = items[i].Element;

      if (item != null && Interlocked.CompareExchange(ref items[i].Element, null, item) == item)

      {

        return item;

      }

    }

    item = Create();

  }

  return item;

}

// Non-inline to improve its code quality as uncommon path

[MethodImpl(MethodImplOptions.NoInlining)]

private T Create() => _fastPolicy?.Create() ?? _policy.Create();



public override void Return(T obj)

{

  if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj)))

  {

    if (_firstItem != null || Interlocked.CompareExchange(ref _firstItem, obj, null) != null)

    {

      var items = _items;

      for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null; ++i)

      {

      }

    }

  }

}

這里用到Interlocked.CompareExchange()方法,Get()方法將items[i].Elementnull進(jìn)行交換,將指定元素設(shè)為 null 并返回原始值。Return()方法將items[i].Element和obj交換后的值不為 null,表示指定元素已經(jīng)歸還,這個方法只有在第一個參數(shù)和第三個參數(shù)相等時才會發(fā)生交換。

說了這么多,我們來看一下對象池具體的用法:

var service = new ServiceCollection();

//使用DefaultObjectPoolProvider

service.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();

//使用默認(rèn)策略

service.AddSingleton<ObjectPool<Foo>>(serviceProvider =>

{

  var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();

  return objectPoolProvider.Create<Foo>();

});

//使用自定義策略

service.AddSingleton<ObjectPool<Foo>>(serviceProvider =>

{

  var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();

  return objectPoolProvider.Create(new FooObjectPoolPolicy());

});



var serviceProvider = _service.BuildServiceProvider();



var objectPool = _serviceProvider.GetService<ObjectPool<Foo>>();



//有借有還,兩次是同一個對象

var item1 = objectPool.Get();

objectPool.Return(item1);

var item2 = objectPool.Get();

Assert.AreEqual(item1, item2);//true



//有借無還,兩次是不同的對象

var item3 = objectPool.Get();

var item4 = objectPool.Get();

Assert.AreEqual(item3, item4);//false

上面的代碼中Foo和FooObjectPoolPolicy是兩個工具類:

public class Foo

{

  public string Id { get; set; }

  public DateTime? CreatedAt { get; set; }

  public string CreatedBy { get; set; }

}



public class FooObjectPoolPolicy : IPooledObjectPolicy<Foo>

{

  public Foo Create()

  {

    return new Foo()

    {

      Id = Guid.NewGuid().ToString("N"),

      CreatedAt = DateTime.Now,

      CreatedBy = "zs"

    };

  }



  public bool Return(Foo obj)

  {

    return true;

  }

}

TIP:當(dāng)你需要控制對象池內(nèi)的對象如何被創(chuàng)建的時候,你可以考慮實(shí)現(xiàn)自定義的IPooledObjectPolicy<T>,反之DefaultPooledObjectPolicy<T>實(shí)現(xiàn)完全可以滿足你的使用。

三、本文小結(jié)

實(shí)現(xiàn)對象池可以考慮ConcurrentBag、Stack、Queue以及BlockingCollection等多種數(shù)據(jù)結(jié)構(gòu),而微軟在.NET Core 中已經(jīng)為我們實(shí)現(xiàn)了一個簡單的對象池,大多數(shù)情況下,我們只需要定義自己的IPooledObjectPolicy去決定對象應(yīng)該怎么樣借、怎么樣還??傊螒蚴澜缋锏?GameObject、數(shù)據(jù)庫里的連接池,都是對象池模式在各自領(lǐng)域中的具體實(shí)現(xiàn)。

TIP:對象池是一種通過復(fù)用對象來減少資源開銷進(jìn)而實(shí)現(xiàn)提高系統(tǒng)性能的軟件設(shè)計(jì)模式,其核心是控制容器內(nèi)對象的生命周期來規(guī)避系統(tǒng)的主動回收,從對象池中借出的對象必須要及時歸還,否則會造成對象池中沒有可用資源。

到此這篇關(guān)于 .NET Core 中對象池 Object Pool的使用的文章就介紹到這了,更多相關(guān) .NET Core 中對象池 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • .NET6新特性之 隱式命名空間引用

    .NET6新特性之 隱式命名空間引用

    本文給大家分享的是 .NET6特新 隱式命名空間引用,如果我們要在新加一個命名空間的引用,可以在項(xiàng)目文件中配置增加<Using Include="命名空間"/>,如果需要移除一個命名空間可以這么做<Using Remove="命名空間"/>,下面來看看文章詳細(xì)介紹內(nèi)容吧,需要的朋友可以參考一下
    2021-11-11
  • .Net 6中的PeriodTimer介紹

    .Net 6中的PeriodTimer介紹

    這篇文章主要介紹了.Net 6中的PeriodTimer,.net 6中新增了一個異步計(jì)時器PeroidTimer,相對普通Timer的回調(diào), 它的模型更簡單,下面一起來看看具體詳情吧
    2022-01-01
  • .Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印詳解

    .Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印詳解

    這篇文章主要為大家介紹了.Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • ASP.NET入門數(shù)據(jù)篇

    ASP.NET入門數(shù)據(jù)篇

    ASP.NET入門數(shù)據(jù)篇...
    2006-07-07
  • ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解

    ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解

    這篇文章主要為大家介紹了ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • .Net性能調(diào)優(yōu)-ArrayPool詳情

    .Net性能調(diào)優(yōu)-ArrayPool詳情

    ArrayPool具有高性能 托管 數(shù)組緩沖池,可重復(fù)使用,用 租用 空間的方式代替 重新分配 數(shù)組空間的行為的特點(diǎn)及可以在頻繁創(chuàng)建和銷毀數(shù)組的情況下 提高性能 ,減少垃圾回收器的壓力的優(yōu)點(diǎn),下面文章內(nèi)容將詳細(xì)對其做介紹,需要的朋友可以參考一下
    2021-09-09
  • ASP.NET Core MVC 過濾器(Filter)

    ASP.NET Core MVC 過濾器(Filter)

    本文小編要給大家介紹的是ASP.NET Core MVC 過濾器,ASP.NET MVC 中的過濾器允許在執(zhí)行管道中的特定階段之前或之后運(yùn)行代碼??梢詫θ?,也可以對每個控制器或每個操作配置過濾器,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-09-09
  • DataGridView控件詳細(xì)介紹

    DataGridView控件詳細(xì)介紹

    DataGridView是用于Windows Froms 2.0的新網(wǎng)格控件。它可以取代先前版本中DataGrid控件,它易于使用并高度可定制,支持很多我們的用戶需要的特性
    2012-11-11
  • ASP.NET MVC Web API HttpClient簡介

    ASP.NET MVC Web API HttpClient簡介

    依稀還記得那個時候用WebClient,HttpWebRequest來發(fā)送一個請求,現(xiàn)在ASP.NET MVC4中自帶了一個類HttpClient;需要的朋友可以參考下
    2012-11-11
  • ABP入門系列應(yīng)用BootstrapTable表格插件

    ABP入門系列應(yīng)用BootstrapTable表格插件

    Bootstrap table是一個開源的輕量級功能非常豐富的前端表格插件。下面通過本文給大家介紹ABP入門系列應(yīng)用BootstrapTable表格插件,感興趣的朋友一起學(xué)習(xí)吧
    2017-03-03

最新評論