简体   繁体   English

ASP.NET,.NET 4.5.1引用的DLL在C#中的对象池

[英]Object Pooling in c# for dll referenced by asp.net, .Net 4.5.1

I am referencing a (black box) dll which has extremely expensive initialization (takes 3-4 seconds). 我指的是一个(黑匣子)dll,它具有非常昂贵的初始化(需要3-4秒)。 It is used by an asp.net application that has several hundred simultaneous users. 有数百个同时用户的asp.net应用程序使用它。

Because of the expensive initialization I cannot use it as an instance variable. 由于初始化费用昂贵,因此无法将其用作实例变量。 My first thought is to store the instance in a static variable and use the c# lock() method to avoid race conditions. 我的第一个想法是将实例存储在静态变量中,并使用c#lock()方法来避免出现竞争情况。 This works fine, but obviously the lock() method around a single static variable is going to be inefficient when multiple users want to access the library simultaneously. 这可以正常工作,但是显然,当多个用户想要同时访问该库时,围绕单个静态变量的lock()方法将效率很低。

I want to implement an object pool so that multiple instances of this library can be employed. 我想实现一个对象池,以便可以使用该库的多个实例。 I can't use COM+. 我不能使用COM +。 What is the best way to implement an object pool in c#, .Net 4.5.1, when the pool will be consumed by an asp.net application? 当ASP.NET应用程序使用该对象池时,在C#.Net 4.5.1中实现对象池的最佳方法是什么?

There are many references to this MSDN article suggesting use of a ConcurrentBag, but many say this works best when a single thread is adding/removing items from the pool. 对此MSDN文章的很多引用都建议使用ConcurrentBag,但是许多人说,当单个线程从池中添加/删除项目时,这种方法最有效。 In my case multiple threads will be adding/removing items, so this approach does not appear to be the right one for asp.net, but if I am wrong in stating that please correct me: https://msdn.microsoft.com/en-us/library/ff458671(v=vs.110).aspx 以我为例,多个线程将要添加/删除项目,因此,这种方法似乎不是适用于asp.net的方法,但是如果我在声明方面有误,请纠正我: https : //msdn.microsoft.com/ zh-CN / library / ff458671(v = vs.110).aspx

I found this answer very informative, but it is dated: C# Object Pooling Pattern implementation 我发现此答案非常有用,但它已过时: C#对象池模式实现

ConcurrentBag is the optimal structure for a object pool. ConcurrentBag是对象池的最佳结构。

You are misinterpreting the advice of "this works best when a single thread is adding/removing items from the pool" . 您误解了“在单个线程从池中添加/删除项目时这种方法最有效”的建议。 A better way to say it would be "A ConcurrentBag works best when the thread removing from the pool has a high chance of being the same thread that put the object in the pool" which is exactly what your object pool will be doing. 更好的说法是“当从池中删除线程时,与将对象放入池中的线程相同的可能性很高, ConcurrentBag工作效果最佳” ,这正是您的对象池将要执行的操作。

The way ConcurrentBag works is each thread has a thread local collection of objects. ConcurrentBag工作方式是每个线程都有一个线程本地对象集合。 When you add to the ConcurrentBag it inserts to that thread local collection, when you remove from the ConcurrentBag it first tries to remove from the thread local collection but if it is empty it goes to another thread and removes it from the other thread's collection. 当您添加到ConcurrentBag它会插入到该线程本地集合中,当您从ConcurrentBag删除时,它首先会尝试从线程本地集合中删除,但如果为空,它将转到另一个线程并将其从另一个线程的集合中删除。

So the reason it is recommend the same thread add as remove is so you don't tie up two lists with locks instead of a single one. 因此,建议添加与删除相同的线程的原因是,这样您就不必将两个带有锁的列表捆绑在一起,而不是将单个列表捆绑在一起。

You can even use a single thread to populate the pool then as workers take items out they will steal from the initialization thread's pool but then return it to their own pool pulling from their own pool from then on. 您甚至可以使用单个线程来填充池,然后当工作人员取出项目时,它们将从初始化线程的池中窃取,但随后将其从自己的池中拉回到自己的池中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM