2009-06-10 12 views
7

मेरे पास एक धागा है जो बाहर निकलता है और कनेक्शन बनाने का प्रयास करता है। धागे में, मैं एक थर्ड पार्टी लाइब्रेरी को कॉल करता हूं। कभी-कभी, यह कॉल लटकती है, और कभी वापस नहीं आती है। यूआई थ्रेड पर, मैं थ्रेड को रद्द करके कनेक्शन प्रयास को रद्द करने में सक्षम होना चाहता हूं, जो तीसरे पक्ष की लाइब्रेरी में लटका कॉल को रोकना चाहिए।आप एक धागे को कैसे संभालें जिसमें लटका हुआ कॉल है?

मैंने थ्रेड.एबॉर्ट कहा है, लेकिन अब थ्रेड पढ़ा है। एबॉर्ट केवल प्रबंधित कोड पर नियंत्रण लौटने पर ही काम करता है। मैंने देखा है कि यह सच है, क्योंकि थ्रेड कभी नहीं निकलता है, और मैं थ्रेड पर बैठा हूं। अब दस मिनट के लिए जुड़ें। इस लटका धागे के साथ मुझे क्या करना चाहिए? क्या मुझे सिर्फ संदर्भ को खाली करना चाहिए और आगे बढ़ना चाहिए? मैं जितना संभव हो उतना साफ होना चाहता हूं -

उत्तर

3

यह समारोह अपने तीसरे पक्ष के पुस्तकालय में एक समय समाप्ति या समारोह को रद्द नहीं है? यदि हां, तो यह बहुत खराब डिजाइन है। कोई सुंदर यहाँ समाधान, मुझे मालूम होता होना करने के लिए ...

दुर्भाग्य से नहीं हो रहा है, वहाँ कोई रास्ता नहीं आप इसे चारों ओर पाने के लिए, मैन्युअल रूप से जो निश्चित रूप से है नहीं धागा को मारने के लिए, Win32 एपीआई का उपयोग कर से कम जा रहे हैं है साफ होने जा रहा है। हालांकि, अगर यह तृतीय-पक्ष लाइब्रेरी आपको कोई अन्य विकल्प नहीं दे रही है, तो यह करने की बात हो सकती है। TerminateThread फ़ंक्शन वह है जिसे आप उपयोग करना चाहते हैं, लेकिन चेतावनी का निरीक्षण करें! इस फ़ंक्शन को पास करने के लिए थ्रेड आईडी प्राप्त करने के लिए, आपको एक और Win32 API कॉल का उपयोग करना होगा (Thread कक्षा इसे सीधे प्रकट नहीं करती है)। यहां प्रबंधित दृष्टिकोण प्रबंधित थ्रेड विधि की शुरुआत में GetCurrentThreadId के परिणामस्वरूप अस्थिर वर्ग चर के मान को सेट करना होगा, और उसके बाद थ्रेड को समाप्त करने के लिए बाद में इस थ्रेड आईडी का उपयोग करें।

4

यादृच्छिक विचार: मुझे आश्चर्य है कि क्या आप एक छोटे कंसोल एक्सई के रूप में दूसरी असेंबली लिख सकते हैं जो इस संचार को करता है ... इसे Process.Start के साथ लॉन्च करें और परिणामों को या तो कैप्चर करें फाइल सिस्टम या stdout intercepting द्वारा। फिर अगर यह लटकता है तो आप प्रक्रिया को मार सकते हैं।

थोड़ा कठोर, शायद - और स्पष्ट रूप से यह एक प्रक्रिया को बढ़ाने के ऊपर है - लेकिन कम से कम इसे मारना संभव है।

+4

"कक्षा से साइट को ले जाएं और नूक करें - यह सुनिश्चित करने का एकमात्र तरीका है।" दरअसल, आप सही हैं; यह गलत व्यवहार कोड को समाप्त करने का एकमात्र गारंटीकृत सुरक्षित तरीका है। Thread.Abort वास्तव में misbehaving धागे को रोकने के लिए गारंटी नहीं है; वास्तव में बुरी तरह से व्यवहार किया धागा गर्भपात को हाइजैक कर सकता है। यहां तक ​​कि एक एपडोमेन लेना भी जरूरी नहीं है जो आप चाहते हैं। यदि आप बिल्कुल, सकारात्मक रूप से व्यवहार किए गए कोड को मारना चाहते हैं तो आपको इसे मारने योग्य प्रक्रिया में अलग करना होगा। –

+0

धन्यवाद रिपली ... मेरा मतलब है ... एरिक ;-p (मैंने हडसन का जवाब दिया होगा, लेकिन मुझे अपने आप पर मॉडरेटर टूल्स का उपयोग करना होगा ...) –

1

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

यदि नहीं, (Win32 के माध्यम से) धागा की हत्या आम तौर पर एक अच्छा विचार नहीं है ...

+0

कॉल कभी वापस नहीं आती है, यही कारण है कि मेरे पास है कृत्रिम रूप से धागे को समाप्त करने के लिए। – MedicineMan

2

सुनिश्चित नहीं है कि यह ऐसा करेगा या स्वीकार्य होगा, लेकिन यह एक शॉट के लायक है।

[DllImport("kernel32.dll")] 
private static extern bool TerminateThread (Int32 id, Int32 dwexit); 

documentation

TerminateThread से एक खतरनाक समारोह है कि केवल सबसे चरम मामलों में इस्तेमाल किया जाना चाहिए है। आपको टर्मिनेट थ्रेड को केवल कॉल करना चाहिए यदि आप जानते हैं कि लक्ष्य थ्रेड क्या कर रहा है, और आप उस कोड को नियंत्रित करते हैं जो टर्म थ्रेड संभवतः समाप्ति के समय चल रहा था। उदाहरण के लिए, टर्मिनेट थ्रेड का परिणाम निम्न समस्याओं में हो सकता है:

  • यदि लक्ष्य धागा एक महत्वपूर्ण अनुभाग का मालिक है, तो महत्वपूर्ण अनुभाग जारी नहीं किया जाएगा।
  • यदि लक्ष्य धागा ढेर से स्मृति आवंटित कर रहा है, तो हीप लॉक जारी नहीं किया जाएगा।
  • यदि लक्ष्य थ्रेड समाप्त होने पर कुछ कर्नेल 32 कॉल निष्पादित कर रहा है, तो थ्रेड की प्रक्रिया के लिए कर्नेल 32 स्थिति असंगत हो सकती है।
  • यदि लक्ष्य धागा साझा डीएलएल की वैश्विक स्थिति में हेरफेर कर रहा है, तो डीएलएल की स्थिति को नष्ट किया जा सकता है, जो डीएलएल के अन्य उपयोगकर्ताओं को प्रभावित करता है।
-1

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

+0

क्या आपने प्रश्न भी पढ़ा –

+0

निश्चित किया - धन्यवाद हालांकि। – Gandalf

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