asp.net,.net 4.5.1引用的dll的c#中的对象池

本文关键字:net dll 对象 引用 asp | 更新日期: 2023-09-27 18:20:37

我引用的是一个(黑盒)dll,它的初始化非常昂贵(需要3-4秒)。它被一个同时拥有数百名用户的asp.net应用程序使用。

由于初始化成本高昂,我无法将其用作实例变量。我的第一个想法是将实例存储在一个静态变量中,并使用c#lock()方法来避免竞争条件。这很好,但很明显,当多个用户希望同时访问库时,围绕单个静态变量的lock()方法效率会很低。

我想实现一个对象池,以便可以使用这个库的多个实例。我不能使用COM+。当对象池将被asp.Net应用程序使用时,在c#,.Net 4.5.1中实现对象池的最佳方法是什么?

有很多参考文献提到这篇MSDN文章建议使用ConcurrentBag,但许多人认为,当单个线程从池中添加/删除项目时,这种方法效果最好。在我的情况下,多个线程将添加/删除项目,因此这种方法似乎不适合asp.net,但如果我说得不对,请纠正我:https://msdn.microsoft.com/en-us/library/ff458671(v=vs.110).aspx

我发现这个答案很有启发性,但它已经过时了:C#对象池模式实现

asp.net,.net 4.5.1引用的dll的c#中的对象池

ConcurrentBag是对象池的最佳结构。

您误解了的建议"当单个线程从池中添加/删除项目时,这最有效"。更好的说法是"当从池中删除的线程很有可能是将对象放入池中的同一个线程时,ConcurrentBag工作得最好"这正是对象池将要做的事情。

ConcurrentBag的工作方式是每个线程都有一个对象的线程本地集合。当您添加到ConcurrentBag时,它会插入到该线程本地集合,当您从ConcurrentBag中删除时,它首先尝试从线程本地集合中删除,但如果它是空的,它会转到另一个线程并从另一线程的集合中删除。

因此,建议使用相同的线程add和remove的原因是,这样就不会将两个列表与锁而不是一个列表捆绑在一起。

您甚至可以使用单个线程来填充池,然后当工作人员取出项目时,他们将从初始化线程的池中窃取项目,然后从那时起从自己的池中将其返回到自己的池中。