सबसे पहले और सबसे महत्वपूर्ण, मैं @briantyler से सहमत हूं: ThreadLocal<T>
या थ्रेड स्थैतिक फ़ील्ड शायद आप जो चाहते हैं। आपको इसके साथ शुरुआती बिंदु के रूप में जाना चाहिए और अन्य विकल्पों पर विचार करना चाहिए यदि यह आपकी आवश्यकताओं को पूरा नहीं करता है।
एक जटिल लेकिन लचीला विकल्प एक सिंगलटन ऑब्जेक्ट पूल है। इसकी सबसे सरल रूप में अपने पूल प्रकार इस तरह दिखेगा:
public sealed class ObjectPool<T>
{
private readonly ConcurrentQueue<T> __objects = new ConcurrentQueue<T>();
private readonly Func<T> __factory;
public ObjectPool(Func<T> factory)
{
__factory = factory;
}
public T Get()
{
T obj;
return __objects.TryDequeue(out obj) ? obj : __factory();
}
public void Return(T obj)
{
__objects.Enqueue(obj);
}
}
यह बहुत उपयोगी प्रतीत नहीं होता है अगर आप, आदिम वर्ग या structs (यानी ObjectPool<MyComponent>
) के मामले में प्रकार T
की सोच रहे हैं पूल इसमें कोई थ्रेडिंग नियंत्रण नहीं है। लेकिन आप या Task<T>
मोनैड के लिए अपने प्रकार T
को प्रतिस्थापित कर सकते हैं, और वही प्राप्त कर सकते हैं जो आप चाहते हैं।
पूल initialisation:
Func<Task<MyComponent>> factory =() => Task.Run(() => new MyComponent());
ObjectPool<Task<MyComponent>> pool = new ObjectPool<Task<MyComponent>>(factory);
// "Pre-warm up" the pool with 16 concurrent tasks.
// This starts the tasks on the thread pool and
// returns immediately without blocking.
for (int i = 0; i < 16; i++) {
pool.Return(pool.Get());
}
उपयोग:
// Get a pooled task or create a new one. The task may
// have already completed, in which case Result will
// be available immediately. If the task is still
// in flight, accessing its Result will block.
Task<MyComponent> task = pool.Get();
try
{
MyComponent component = task.Result; // Alternatively you can "await task"
// Do something with component.
}
finally
{
pool.Return(task);
}
यह विधि एक ThreadLocal
या धागे स्थिर क्षेत्र में अपने घटक को बनाए रखने से कहीं अधिक जटिल है, लेकिन आप कुछ सीमित की तरह कल्पना करने की ज़रूरत है, तो पूल किए गए उदाहरणों की संख्या, पूल अमूर्तता काफी उपयोगी हो सकती है।
संपादित
बेसिक "एक्स उदाहरणों का सेट स्थायी" एक Get
साथ पूल कार्यान्वयन पूल एक बार ब्लॉक सूखा किया गया है जो:
public sealed class ObjectPool<T>
{
private readonly Queue<T> __objects;
public ObjectPool(IEnumerable<T> items)
{
__objects = new Queue<T>(items);
}
public T Get()
{
lock (__objects)
{
while (__objects.Count == 0) {
Monitor.Wait(__objects);
}
return __objects.Dequeue();
}
}
public void Return(T obj)
{
lock (__objects)
{
__objects.Enqueue(obj);
Monitor.Pulse(__objects);
}
}
}
स्रोत
2016-02-10 03:45:07
घटक के बारे में अधिक जानना चाहते हैं। 1) क्या यह एक COM घटक है? 2) आप डब्ल्यूसीएफ सेवा कैसे होस्ट करते हैं? आईआईएस? एक विंडोज सेवा के अंदर? कंसोल ऐप? 3) डब्ल्यूसीएफ सेवा का इंस्टेंस कंट्रोल क्या है? सिंगलटन? प्रति कॉल? प्रति सत्र? – MickyD
@MickyD ने जो कहा है उसके शीर्ष पर, घटक का एक नया उदाहरण बनाने के लिए कॉल को थ्रेड करना आपके थ्रेड सुरक्षा समस्या को हल नहीं करता है (मुझे लगता है कि यह वास्तव में इसे और भी खराब बनाता है)। – AWinkle
ऐसा लगता है कि आपको वास्तव में क्या चाहिए, एक ऑब्जेक्ट पूल है, न कि थ्रेड पूल। –