2012-04-12 18 views
5

मैंने SerialPort वर्ग और ThreadPool.QueueUserWorkItem या Task एस का उपयोग कर अपने सी # .Net 4.0 एप्लिकेशन में एक रोचक समस्या में भाग लिया है।सीरियलपोर्ट संचार के लिए नेट थ्रेड बनाम थ्रेडपूल बनाम कार्य

समस्या केवल तब होती है जब मैं 2 या अधिक सीरियल पोर्ट्स का उपयोग करता हूं। प्रत्येक सीरियल पोर्ट का अपना सूत्र में चलाता है कि मैं 3 में से 1 तरीकों से बनाने के लिए:

  1. new Thread(DoSerialCommX)
  2. ThreadPool.QueueUserWorkItem(DoSerialCommX)
  3. new Task(DoSerialCommX, TaskCreationOptions.LongRunning).Start()

समस्या समझने के लिए, मैं अपने DoSerialCommX विधि बनाई पढ़ने के लिए और लूप में हमेशा के लिए धारावाहिक बंदरगाह को लिखें। ऐसा कुछ ऐसा दिखता है: (मैं वास्तव में अपने असली कार्यक्रम में ऐसा नहीं कर रहा हूं। यह सिर्फ मेरे परीक्षण कार्यक्रम से एक स्निपेट है जो समस्या को अलग करता है और दिखाता है)।

private void DoSerialCommX() 
{ 
    SerialPort port = new SerialPort("ComX", 9600); 
    port.Open(); 

    while(true) 
    { 
     //Read and write to serial port 
    } 
} 

अगर मैं किसी भी विधि 2 या 3, धारावाहिक संचार stutters का उपयोग करें और मैं कई संचार समय समाप्ति प्राप्त करते हैं। अगर मैं विधि 1 का उपयोग करता हूं, तो सब अच्छा है। साथ ही, मुझे यह उल्लेख करना चाहिए कि यह केवल मेरे इंटेल एटम आधारित पीसी पर होता है। डेस्कटॉप पीसी में कोई समस्या नहीं है।

मुझे पता है कि थ्रेड पूल थ्रेड का उपयोग करता है, और डिफ़ॉल्ट रूप से Task थ्रेड पूल का उपयोग करता है। और मुझे पता है कि थ्रेड पूल वास्तव में अल्पकालिक परिचालन के लिए है। लेकिन मैंने TaskCreationOptions.LongRunning का उपयोग करने का प्रयास किया, जिसे मैंने थ्रेड पूल का उपयोग करने के बजाय समर्पित धागे को जन्म दिया था, लेकिन यह अभी भी काम नहीं कर रहा था।

तो प्रश्न:Thread इस स्थिति में इतना खास बनाता है? क्या Thread के बारे में कुछ है जो आईओ संचालन के लिए बेहतर अनुकूल बनाता है?

संपादित करें: जवाब अब तक कि मैं एक कभी न खत्म होने की प्रक्रिया के लिए ThreadPool या कार्यों का उपयोग करने के लिए कोशिश कर रहा हूँ ग्रहण करने के लिए लग रहे हैं। मेरे असली आवेदन में यह मामला नहीं है। मैं केवल समस्या को दर्शाने के लिए ऊपर दिए गए कोड में कभी-कभी समाप्त होने वाला लूप का उपयोग नहीं कर रहा हूं। मुझे वास्तव में जानने की जरूरत है कि क्यों Thread काम करता है और ThreadPool और Task नहीं। उन लोगों के बारे में तकनीकी रूप से अलग क्या है जो सीरियल संचार को हिचकी का कारण बनेंगे?

+0

मुझे लगता है कि यह एक मूर्ख सवाल है, लेकिन आप> = 25 धागे को प्रबंधित करने की कोशिश नहीं कर रहे हैं, है ना? – Jeff

+0

@ जेफएन 825, नहीं, प्रति सीरियल पोर्ट में केवल 1 धागा है, और मैं अधिकतम 4 धारावाहिक बंदरगाहों में उपयोग कर रहा हूं। – Verax

+0

1 और 3 समान हैं। –

उत्तर

2

दार्शनिक रूप से 1, 2 और 3 के बीच थोड़ा अंतर होता है कि कैसे थ्रेड निष्पादित होता है। वे सभी एक ही डिफ़ॉल्ट निष्पादन प्राथमिकता साझा करते हैं जब तक आप इसे ओवरराइड नहीं करते - वास्तव में थ्रेड शेड्यूलर उन्हें शेड्यूल करने के लिए समान रणनीति का उपयोग करेगा। वे सभी लूप में खुशी से कताई बैठेंगे।

मुझे लगता है तरीकों के बीच बड़ा अंतर है:

  1. बुनियादी ढांचे की लागत (सूत्र, स्मृति आदि) अपने निष्पादन के साथ जो सभी घड़ी के लिए संघर्ष होगा # 2 और # 3 की ThreadPool timeslices समर्थन करने के लिए ऊपर काता पाश।
  2. कम मांसपेशी एटम पर थ्रेड संदर्भ स्विचिंग लागत। एटम में एक छोटे कैश हैं, और छोटी प्रोसेसिंग पाइपलाइन (ओं)। अधिक चलने वाले धागे = अधिक संदर्भ स्विच, पाइपलाइन (ओं) और कम निर्देश कैश दक्षता के अधिक डंपिंग।

विधि 2 और 3 के कार्यात्मक बिंदु के उपयोग से कुछ हद तक अपमानजनक है - आपका इरादा विधि से बाहर नहीं निकलना है। इन रणनीतियों को परमाणु, परिमित संचालन, और आईओ कॉम्प्लेशन पोर्ट कार्यों जैसे कि एसिंक नेटवर्क, डिस्क ऑपरेशंस इत्यादि के लिए अनुकूल कुछ हद तक निष्पादित निष्पादन के लिए अनुकूलित किया गया है ... (शायद आपके सीरियल पोर्ट कोड के लिए भी संभावना है?)

मैं चाहता हूं 2 & 3 छोड़ें जब तक कि आप Async IO को अपनाने में रुचि रखते हैं। थ्रेड पर फ़ोकस करें - ऐसा लगता है कि आप बेहतर अनाज, अनुमानित निष्पादन नियंत्रण चाहते हैं, बिना थ्रेडपूल लाता है। जो समय समाप्ति के कारण होता है -

+1

यह एक 9600-बॉड सीरियल पोर्ट है! एक चरित्र प्रत्येक मिलीसेकंद। यूएआरटी में हार्डवेयर बफर है, ड्राइवर के पास बफर है। यह लगभग विश्वास से परे है कि इनमें से दो बिंदुओं में से कोई भी मुद्दा हो सकता है। –

+0

मेरा असस परमाणु संचालित लैपटॉप, (!) खुशी से बिना किसी समस्या के 115 किलोबाड पर दो धारावाहिक बंदरगाह चलाएगा। यह सामान्य रूप से हार्डवेयर नहीं है, (हालांकि, निश्चित रूप से, ओपी का बॉक्स खराब हो सकता है)। –

0

मामूली अंतर हैं:

  • थ्रेड का उपयोग करते हुए स्पष्ट रूप से एक नया थ्रेड से उत्पन्न होने वाला Thread.Start() कहा जाता है - और यह अपने कोड विशिष्ट क्षण है कि चलाता है कि सुनिश्चित करता है।
  • थ्रेडपूल का उपयोग सुनिश्चित करता है कि आंतरिक थ्रेडपूल तर्क के अनुसार निकट भविष्य में एक थ्रेड खोला जाएगा। चूंकि थ्रेडपूल संख्या लंबे समय तक (या अनंत) चल रहे संचालन के लिए इसका उपयोग करने के लिए सलाह दी जाती है।
  • कार्य का उपयोग केवल यह निर्धारित करेगा कि कोड चलाएगा। या तो पर एक और धागा या यहां तक ​​कि मुख्य धागे पर भी यह सुनिश्चित नहीं करता है कि यह तुरंत चलाएगा या अलग-अलग कार्य धागे पर चलेंगे।

और यदि आप चाहते हैं कि आपका कार्य जल्दी से शुरू हो जाए तो हमेशा थ्रेड का उपयोग करें। कार्य और थ्रेडपूल दोनों में कुछ अतिरिक्त "इंफ्रास्ट्रक्चर ओवरहेड" है जो आपके द्वारा देखी गई मामूली देरी का कारण बन सकता है।

चूंकि आपका कार्य कभी मौजूद नहीं होने पर थ्रेडपूल और कार्य दोनों का उपयोग नहीं किया जाता है, इसलिए मेरा सुझाव है कि आप थ्रेड का उपयोग करें।

1

मुझे संदेह है कि ऐसा होता है क्योंकि आप एक COM पोर्ट से पढ़ रहे/लिख रहे हैं। उस कारक के बिना इन सभी को समान रूप से प्रदर्शन करना चाहिए क्योंकि (यदि आप जांचते हैं) वे सभी सामान्य प्राथमिकता वाले थ्रेड में चल रहे हैं।

शायद I/O completion ports और थ्रेड पूल पर पढ़ने के लिए यह देखने के लिए कि क्या यह अजीब व्यवहार समझा सकता है।

+0

मुझे लगता है कि आप बिल्कुल सही हैं। धारावाहिक बंदरगाह इस समस्या का एक प्रमुख घटक है। क्या आप शायद I/O पूर्णता पोर्ट सुझाव पर विस्तार कर सकते हैं? I12 O Completion बंदरगाहों के काम के तरीके के बारे में अधिक जानकारी के लिए – Verax

+0

यह भी देखें http://hi.baidu.com/jrckkyy/blog/item/401422527c131b070df3e37b.html। –

1

आपके कोड, आपके ड्राइवर या आपके हार्डवेयर के साथ कुछ बंद है जिसने आपके सीरियल पोर्ट प्रदर्शन को 'किनारे पर' रखा है, जो कि हर समय काम नहीं करने के कगार पर है। समर्पित थ्रेड या थ्रेडपूल का उपयोग करने में कोई समस्या नहीं होनी चाहिए, (मॉड। एक सीरियल पोर्ट को पढ़ने के लिए थ्रेडपूल थ्रेड का उपयोग करके)।

दो 9600-बॉड धारावाहिक बंदरगाह आप एक अबाकस के साथ भाग सकते हैं, मोतियों और तारों को अच्छी तरह से तेल लगाते हैं।

+0

पुह। मैं आसानी से एक जंगली abacus पर दो 9600-बॉड धारावाहिक बंदरगाह चला सकते हैं। –

+0

यह आपके लिए ठीक है। आप शायद हाइपरबैड्स के साथ एक बहुआयामी abacus है। –

संबंधित मुद्दे