asp.net、.Net 4.5.1 引用的 dll 在 c# 中的对象池
Object Pooling in c# for dll referenced by asp.net, .Net 4.5.1
我正在引用一个(黑匣子)dll,它的初始化非常昂贵(需要 3-4 秒)。它由具有数百个并发用户的 asp.net 应用程序使用。
由于昂贵的初始化,我不能将它用作实例变量。我的第一个想法是将实例存储在静态变量中并使用 c# lock() 方法来避免竞争条件。这工作正常,但显然当多个用户想要同时访问该库时,围绕单个静态变量的 lock() 方法效率低下。
我想实现一个对象池,以便可以使用该库的多个实例。我不能使用 COM+。当池将被 asp.net 应用程序使用时,在 c#、.Net 4.5.1 中实现对象池的最佳方法是什么?
这篇 MSDN 文章有很多参考资料,建议使用 ConcurrentBag,但很多人说,当单个线程是池中的 adding/removing 项时,这种方法效果最好。在我的例子中,多个线程将是 adding/removing 个项目,因此这种方法似乎不适合 asp.net,但如果我说错了请纠正我:https://msdn.microsoft.com/en-us/library/ff458671(v=vs.110).aspx
我发现这个答案非常有用,但它已过时:C# Object Pooling Pattern implementation
ConcurrentBag
是对象池的最佳结构。
您误解了 "this works best when a single thread is adding/removing items from the pool" 的建议。更好的说法是 "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" 这正是您的对象池将要执行的操作。
ConcurrentBag
的工作方式是每个线程都有一个线程本地对象集合。当您添加到 ConcurrentBag
时,它会插入到该线程本地集合中,当您从 ConcurrentBag
中删除时,它首先尝试从线程本地集合中删除,但如果它是空的,它将转到另一个线程并删除它来自另一个线程的集合。
所以建议使用相同的线程添加和删除的原因是这样你就不会用锁绑定两个列表而不是一个。
您甚至可以使用单个线程来填充池,然后当工作人员取出项目时,他们将从初始化线程的池中窃取,然后 return 从那时起,它会从他们自己的池中提取到他们自己的池中.
我正在引用一个(黑匣子)dll,它的初始化非常昂贵(需要 3-4 秒)。它由具有数百个并发用户的 asp.net 应用程序使用。
由于昂贵的初始化,我不能将它用作实例变量。我的第一个想法是将实例存储在静态变量中并使用 c# lock() 方法来避免竞争条件。这工作正常,但显然当多个用户想要同时访问该库时,围绕单个静态变量的 lock() 方法效率低下。
我想实现一个对象池,以便可以使用该库的多个实例。我不能使用 COM+。当池将被 asp.net 应用程序使用时,在 c#、.Net 4.5.1 中实现对象池的最佳方法是什么?
这篇 MSDN 文章有很多参考资料,建议使用 ConcurrentBag,但很多人说,当单个线程是池中的 adding/removing 项时,这种方法效果最好。在我的例子中,多个线程将是 adding/removing 个项目,因此这种方法似乎不适合 asp.net,但如果我说错了请纠正我:https://msdn.microsoft.com/en-us/library/ff458671(v=vs.110).aspx
我发现这个答案非常有用,但它已过时:C# Object Pooling Pattern implementation
ConcurrentBag
是对象池的最佳结构。
您误解了 "this works best when a single thread is adding/removing items from the pool" 的建议。更好的说法是 "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" 这正是您的对象池将要执行的操作。
ConcurrentBag
的工作方式是每个线程都有一个线程本地对象集合。当您添加到 ConcurrentBag
时,它会插入到该线程本地集合中,当您从 ConcurrentBag
中删除时,它首先尝试从线程本地集合中删除,但如果它是空的,它将转到另一个线程并删除它来自另一个线程的集合。
所以建议使用相同的线程添加和删除的原因是这样你就不会用锁绑定两个列表而不是一个。
您甚至可以使用单个线程来填充池,然后当工作人员取出项目时,他们将从初始化线程的池中窃取,然后 return 从那时起,它会从他们自己的池中提取到他们自己的池中.