2008-11-27 8 views
5

यहां मेरे लिए अपेक्षाकृत सामान्य कार्य है, और, मुझे लगता है कि, कई .NET प्रोग्रामर के लिए:
मैं किसी दिए गए प्रकार को संसाधित करने की आवश्यकता वाले वर्कर थ्रेड को शेड्यूल करने के लिए .NET थ्रेडपूल का उपयोग करना चाहता हूं कार्य।जेनेटिक थ्रेडपूल .NET

एक पुनश्चर्या के रूप में, ThreadPool और उसके संबंधित प्रतिनिधि की कतार विधि के लिए हस्ताक्षर कर रहे हैं:

public class Worker<T> { 
    public void schedule(T i_task) { 
     ThreadPool.QueueUserWorkItem(execute, i_task) 
    } 
    private void execute(Object o){ 
     T task = (T)o; //What happened to the type safety? 
     executeTask(task); 
    } 
    private void executeTask(T i_task){ 
     //process i_task 
    } 
} 

:

public static bool QueueUserWorkItem (
    WaitCallback callBack, 
    Object state 
) 
public delegate void WaitCallback (Object state) 

इसलिए, एक ठेठ सामान्य कार्यकर्ता धागा वर्ग कुछ ऐसा दिखाई देगा state पैरामीटर के प्रकार पर ध्यान दें? यह Object है!

एनईटी टीम ने QueueUserWorkItem विधि (या पूरे ThreadPool कक्षा) सामान्य बनाने के लिए क्यों चुना है? मुझे विश्वास नहीं है कि उन्होंने इसे अनदेखा किया है।

यहां बताया गया है कि मैं इसे देखना चाहते हैं:

//in the ThreadPool class: 
public static bool QueueUserWorkItem<T> (
    WaitCallback<T> callBack, 
    T state 
) 
public delegate void WaitCallback<T> (T state) 

इस कार्यकर्ता वर्ग प्रकार सुरक्षित (और एक बहुत साफ, IMHO) बनाना होगा:

public class Worker<T> { 
    public void schedule(T i_task) { 
     ThreadPool.QueueUserWorkItem<T>(execute, i_task) 
    } 
    private void execute(T i_task){ 
     //process i_task 
    } 
} 

मुझे याद आ जाना चाहिए कुछ कुछ।

उत्तर

5

ऐसा लगता है जैसे आप एक कार्य कतार के बारे में बात कर रहे हैं? (और मैं क्लिपपी की तरह लग रहा हूं ...)

रिकॉर्ड के लिए, थ्रेड-पूल थ्रेड आमतौर पर काम के छोटे टुकड़ों के लिए उपयोग किया जाना चाहिए। आपको एक लंबे समय तक रहने वाली कतार के लिए आदर्श रूप से अपना खुद का धागा बनाना चाहिए। ध्यान दें कि .NET 4.0 सीसीआर/टीपीएल पुस्तकालयों को अपनाया जा सकता है, इसलिए हमें कुछ अंतर्निहित कार्य कतार मुफ्त में मिलेंगी - लेकिन थ्रेडेड वर्क-कतार लिखना मुश्किल नहीं है। और आप इसे, जेनेरिक भी ;-p कर सकते हैं

पुन प्रश्न - मैं धागे में राज्य पारित करने के लिए कब्जा कर लिया चर प्रक्रिया अपनाते हैं (वे हो Thread, ThreadPool, या Control.Invoke):

Thread t = new Thread(() => SomeMethod(arg)); 
    t.IsBackground = true; 
    t.Name = "Worker n"; 
    t.Start(); 

इससे ThreadPool को संतृप्त किए बिना, थ्रेड पर आप अधिक बारीक नियंत्रण करते हैं।

+2

मैं निष्पादन 'अंतर्निहित एक काम कतार के परत के रूप में एक धागा पूल का उपयोग नहीं कर के अपने तर्क समझ में नहीं आता तोड़ने के लिए नहीं चुना है। * * * का उपयोग करते समय यह एक समस्या है।नेट थ्रेडपूल क्लास सीमित संख्या में थ्रेड के कारण? आईएमओ काम करना कतार में कार्यों को मानना ​​स्वाभाविक है। क्या आप विस्तार से बता सकते हैं? –

7

चूंकि किसी भी अज्ञात प्रतिनिधि या लैम्ब्डा को थ्रेडपूल (परिवर्तनीय कैप्चर के माध्यम से) पास करके आप जो भी राज्य पसंद करते हैं, उसे पैकेज करने के लिए तुच्छ है, इसलिए सामान्य संस्करण की आवश्यकता नहीं है।

उदाहरण के लिए, यदि आप एक उपयोगिता समारोह लिख सकते हैं:

static void QueueItem<T>(Action<T> action, T state) 
{ 
    ThreadPool.QueueUserWorkItem(delegate { action(state); }); 
} 

लेकिन यह बहुत उपयोगी नहीं होगा, जैसा कि आप बस एक प्रतिनिधि खुद के किसी भी समय आप जमा कार्य में राज्य की जरूरत का उपयोग कर सकते हैं।

1

थ्रेडपूल .NET 1.1 के बाद मौजूद है जिसमें जेनेरिक नहीं थे।

मुझे पसंद है कि वे किस तरह पश्च संगतता :-)

+5

मुझे नहीं लगता कि यह एक वैध तर्क है। बस 1.1 में सभी कंटेनर कक्षाओं को देखें जो 2.0 में जेनिक्स का उपयोग करने के लिए "अपग्रेड" हो गए हैं। इसके अलावा मैं * क्यूई * विधि को इसके सामान्य समकक्ष के साथ प्रतिस्थापित करने का सुझाव नहीं दे रहा था, लेकिन इसके साथ जेनेरिक संस्करण जोड़ने के लिए। –