激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - .NET Core 中對象池 Object Pool的使用

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

2021-12-22 15:08494324190 ASP.NET教程

這篇文章主要介紹了 .NET Core 中對象池 Object Pool的使用,對象池簡單來說就是一種為對象提供可復(fù)用能力的軟件設(shè)計思路,對象池最常用的場景是游戲設(shè)計,因為在游戲中大量存在著可復(fù)用的對象,源源不斷的子彈出現(xiàn)并不是循環(huán)再

一、什么是對象池

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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)為我們提供了對象池的實現(xiàn),即Microsoft.Extensions.ObjectPool。它主要提供了三個核心的組件,分別是ObjectPoolObjectPoolProviderIPooledObjectPolicyObjectPool是一個抽象類,對外提供了Get和Return兩個方法,這就是所謂的有借有還。ObjectPoolProvider同樣是一個抽象類,它的職責(zé)就是創(chuàng)建ObjectPool,它提供了兩個Create方法,兩者的區(qū)別是無參數(shù)版本本質(zhì)上使用的是DefaultPooledObjectPolicy。它和DefaultObjectPool、DefaultObjectPoolProvider都是微軟提供的默認(rèn)實現(xiàn),IPooledObjectPolicy可以為不同的對象池定義不同的策略,來決定對象如何借、是否可以還。DefaultObjectPool內(nèi)部使用ObjectWrapper[]來管理對象,ObjectWrapper[]的大小等于 maximumRetained-1,默認(rèn)情況下maximumRetained等于Environment.ProcessorCount * 2,這里主要用到了Interlocked.CompareExchange()方法,

具體代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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ā)生交換。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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是兩個工具類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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)建的時候,你可以考慮實現(xiàn)自定義的IPooledObjectPolicy<T>,反之DefaultPooledObjectPolicy<T>實現(xiàn)完全可以滿足你的使用。

三、本文小結(jié)

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

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

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

原文鏈接:https://blog.51cto.com/u_11739124/4640260

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人区一区二区 | 中文字幕欧美一区二区三区 | 午夜人体| 无码专区aaaaaa免费视频 | 欧美成人一级 | 亚洲一区二区三区精品在线观看 | 久久2019中文字幕 | 成人午夜精品久久久久久久蜜臀 | 黄色网址免费进入 | 成人在线免费视频观看 | 欧美亚洲免费 | 鸥美一级片| 羞羞的视频免费观看 | 国产欧美日韩视频在线观看 | 毛片视频网站在线观看 | 9797色| 亚洲性生活免费视频 | av电影免费在线 | 中国黄色一级生活片 | 国产成人精品自拍视频 | 国产91精品久久久久久 | 日韩电影毛片 | 欧美日韩在线免费观看 | 国产成人精品一区二区仙踪林 | 精品国产91久久久久久久 | 一级黄色免费 | 嗯哈~不行好大h双性 | 日本一区二区三区视频在线 | 欧美三区在线 | 久久亚洲精品久久国产一区二区 | 国产精品久久久久av | 欧美一级黑人 | 免费永久在线观看黄网 | 91精品国产刺激国语对白 | 在线视频成人永久免费 | 日本不卡一区在线观看 | 成人免费电影av | 欧美女优一区 | 深夜激情视频 | 中文字幕在线看第二 | 国产91影院|