2015-11-04 47 views
0

我引用了一個具有非常昂貴的初始化(需要3-4秒)的(黑盒)dll。它由具有幾百個併發用戶的asp.net應用程序使用。c#中的對象池由asp.net,.Net引用的dll 4.5.1

由於昂貴的初始化,我不能將它用作實例變量。我的第一個想法是將實例存儲在一個靜態變量中,並使用c#lock()方法來避免競爭條件。這工作正常,但顯然當多個用戶想要同時訪問該庫時,圍繞單個靜態變量的lock()方法將效率低下。

我想實現一個對象池,以便可以使用此庫的多個實例。我無法使用COM +。在c#,.Net 4.5.1中實現對象池的最佳方式是什麼時候,asp.net應用程序將使用該池?

有許多關於這個MSDN文章建議使用ConcurrentBag的參考文獻,但許多人認爲當單個線程從池中添加/刪除項目時,效果最好。在我的情況下,多線程將添加/刪除項目,所以這種方法似乎不是正確的一個asp.net,但如果我錯了,說明請糾正我:https://msdn.microsoft.com/en-us/library/ff458671(v=vs.110).aspx

我發現這個答案非常但它的日期是:C# Object Pooling Pattern implementation

+1

您接受的問題中的[接受的答案](http://stackoverflow.com/a/30664859/1144943)指的是Roslyn,並且只有幾個月的時間。對象池的實現(其中之一)可以在[這裏]找到(https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/SharedCollections/ObjectPool%601.cs) –

回答

1

ConcurrentBag是對象池的最佳結構。

您錯誤地解釋了的建議「當單個線程正在從池中添加/刪除項目時,此功能效果最佳」。一種更好的方式來說這將是「A ConcurrentBag」當從池中刪除線程很有可能成爲將對象放入池中的相同線程的最佳效果時,「」正是您的對象池將要執行的操作。

工作方式ConcurrentBag作品是每個線程都有一個線程本地收集的對象。當您添加到ConcurrentBag時,它將插入到該線程的本地集合中,當您從ConcurrentBag中刪除時,它首先嚐試從線程本地集合中刪除,但如果它是空的,它將轉到另一個線程並將其從另一個線程的集合中刪除。

所以推薦相同的線程添加刪除的原因是所以你不綁定兩個列表與鎖而不是一個單一的。

你甚至可以使用單個線程來填充池,然後當工作人員拿出物品時,他們將從初始化線程的池中竊取,然後將其從自己的池中返回到他們自己的池中。

+0

優秀,謝謝你打在頭上的指甲。 –

+0

如果您想了解如何在asp.net應用程序中使用該代碼的後續問題:http://codereview.stackexchange.com/questions/109924/using-the-concurrentbag-as-an-object -pool換ASP網應用 –