2012-11-01 6 views
5

मैं वर्तमान में आरएफआईडी-कार्ड के साथ संचार के लिए विजुअल स्टूडियो 2012 में एक सॉफ्टवेयर लिख रहा हूं। मुझे कार्ड रीडर के साथ संचार को संभालने के लिए डेल्फी में लिखा गया एक डीएलएल मिला।सी # एप्लिकेशन अप्रबंधित डीएलएल के साथ पूरे सिस्टम को फ्रीज करता है

समस्या यह है: मेरा सॉफ़्टवेयर मशीनों पर ठीक चल रहा है, जिसमें VS2012 स्थापित है। अन्य प्रणालियों पर यह स्वयं या पूरी प्रणाली को जमा करता है। मैंने इसे x32 और x64 विन्यास के साथ Win XP/7/8 पर आज़माया। मैं .NET 4.0 का उपयोग कर रहा हूं।

पाठक से कनेक्ट करने के बाद, सॉफ़्टवेयर एक पृष्ठभूमि शुरू करता है, जो पाठकों (200 एमएस दर पर) पाठक आरएफ-फील्ड में सूची कार्ड के लिए कमांड के साथ पाठक (200ms दर पर) करता है। दुर्घटना हमें सीए होती है। पाठक कनेक्ट होने के 10 से 20 सेकंड बाद।

[DllImport("tempConnect.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern int inventory(int maxlen, [In] ref int count, 
             IntPtr UIDs, UInt32 HFOffTime); 
public String getCardID() 
    { 
     if (isConnectet()) 
     { 
      IntPtr UIDs = IntPtr.Zero; 
      int len = 2 * 8; 
      Byte[] zero = new Byte[len]; 
      UIDs = Marshal.AllocHGlobal(len); 
      Thread.Sleep(50); 
      Marshal.Copy(zero, 0, UIDs, len); 
      int count = 0; 
      int erg; 
      String ret; 
      try 
      { 
       erg = inventory(len, ref count, UIDs, 50); 
      } 
      catch (ExternalException) // this doesn't catch anything (iI have set <legacyCorruptedStateExceptionsPolicy enabled="true"/>) 
      { 
       return "\0"; 
      } 
      finally 
      { 
       ret = Marshal.PtrToStringAnsi(UIDs, len); 
       IntPtr rslt = LocalFree(UIDs); 
       GC.Collect(); 
      } 
      if (erg == 0) 
       return ret; 
      else 
       return zero.ToString(); 
     } 
     else 
      return "\0"; 
    } 

DLL डेल्फी में लिखा है, कोड DLL आदेश है:: यहाँ कोड है

function inventory (maxlen: Integer; var count: Integer; 
        UIDs: PByteArray; HFOffTime: Cardinal = 50): Integer; STDCALL; 

मैं एक स्मृति रिसाव कहीं भी हो सकते हैं लगता है, लेकिन मैं कोई अंदाज़ा नहीं है उसे ढूंढने का तरीका ...


संपादित करें:

मैंने उपरोक्त मेरे कोड में कुछ विचार (स्पष्ट जीसी। कोलेक्ट(), कोशिश-अंत-अंत में) जोड़ा, लेकिन यह अभी भी काम नहीं करता है।

if (!bgw_inventory.IsBusy) 
    bgw_inventory.RunWorkerAsync(); 

Async BackgroundWorker करता है::

private void bgw_inventory_DoWork(object sender, DoWorkEventArgs e) 
    { 
      if (bgw_inventory.CancellationPending) 
     { 
      e.Cancel = true; 
      return; 
     } 
     else 
     { 
      String UID = reader.getCardID(); 
      if (bgw_inventory.CancellationPending) 
      { 
       e.Cancel = true; 
       return; 
      } 
      if (UID.Length == 16 && UID.IndexOf("\0") == -1) 
      { 
       setCardId(UID); 
       if (!allCards.ContainsKey(UID)) 
       { 
        allCards.Add(UID, new Card(UID)); 
       } 
       if (readCardActive || deActivateCardActive || activateCardActive) 
       { 
        if (lastActionCard != UID) 
         actionCard = UID; 
        else 
         setWorkingStatus("OK", Color.FromArgb(203, 218, 138)); 
       } 
      } 
      else 
      { 
       setCardId("none"); 
       if (readCardActive || deActivateCardActive || activateCardActive) 
        setWorkingStatus("waiting for next card", Color.Yellow); 
      } 
     } 
    } 

संपादित

कार्रवाई, कि हर 200 मि.से चलाता है:

यहाँ कोड, कि getCardID() कहता है

टीआई अब मैं कोड पर कुछ छोटे reworks (ऊपर अद्यतन) बना दिया होगा। अब केवल ऐप। "tempConnect.dll" पर 0xC00000FD (स्टैक ओवरफ़्लो) के साथ क्रैश। यह वीएस2012 के साथ सिस्टम पर स्थापित नहीं होता है या यदि मैं देशी डेल्फी के साथ डीएलएल का उपयोग करता हूं! क्या किसी के पास कोई अन्य विचार है?


संपादित

अब मैं DLL प्रवेश करने यह stacksize है बना दिया है और कुछ अजीब पाया: यह कहा जाता है और मेरी सी # डेबूटस्ट्रैप से सर्वेक्षण में शामिल रहा है, stacksize लगातार ऊपर और नीचे बदल रहा है। यदि मैं प्राकृतिक डीप्ली कार्यक्रम से ऐसा करता हूं तो स्टैक्सइज़ स्थिर है! तो मैं और जांच करूँगा, लेकिन मुझे वास्तव में कोई विचार नहीं है, मुझे क्या खोजना है ...

+0

सिर्फ एक संदेह है, मुझे नहीं लगता कि यह आपकी समस्या से संबंधित है, लेकिन 'सूची()' फ़ंक्शन को कॉल करने के बाद कोड का विश्लेषण करके, आप जांच रहे हैं कि यूआईडीएस शून्य नहीं है या नहीं। इस निर्माण से पता चलता है कि यूआईडीएस का मूल्य 'सूची 'फ़ंक्शन के अंदर शून्य हो सकता है। यदि ऐसा है - क्या आप संदर्भ द्वारा यूआईडीएस को पंसद नहीं कर रहे हैं? –

+0

'मार्शल.फ्रीएचजीएलबल()' तक पहुंचने से पहले, आंतरिक कोड को पकड़ने वाले हैंडलर के अंदर फेंक दिया गया अपवाद होने पर वर्तमान कोड रिसाव हो सकता है। मैं इस हैंडलर को 'आखिरकार' खंड में जोड़ने का सुझाव दूंगा जहां 'मार्शल' फ्री कॉलग्लोबल() 'को कॉल किया गया है। इस तरह आप सुनिश्चित करते हैं कि कुछ गलत होने पर भी आवंटित स्मृति मुक्त हो जाती है। मैं कैच क्लॉज के अंदर त्रुटि को लॉगिंग करने का भी सुझाव दूंगा, क्योंकि इस पल में आप यह नहीं बता सकते कि 'शून्य.ToString()' का रिटर्न वैल्यू 'इन्वेंट्री()' द्वारा लौटाया गया वैध मूल्य है, या कुछ गलत हो गया है । –

+0

क्या आप कोड प्राप्त कर सकते हैं जो 'getCardID() 'को कॉल कर रहा है? कारण मैं यह पूछता हूं कि यह सत्यापित करने के लिए कि कोई भी संभावना नहीं है कि सूची() को एक से अधिक धागे द्वारा समवर्ती रूप से बुलाया जा सकता है। यदि इसे थ्रेड-सुरक्षित होने के लिए डिज़ाइन नहीं किया गया है, तो यह आपके द्वारा अनुभव किए जा रहे फ्रीज का कारण हो सकता है। चीयर्स! –

उत्तर

1

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

.NET में मेमोरी लीक खोजने के लिए कुछ अच्छी तकनीकों के लिए this question देखें - इससे आपको जानकारी मिल जाएगी कि आपके कोड के प्रबंधित अंत में स्मृति का उपयोग कैसे किया जा रहा है (यानी, वह हिस्सा जो आप सीधे कर सकते हैं नियंत्रण)। सिस्टम के समग्र स्वास्थ्य पर नजर रखने के लिए ब्रेकपॉइंट्स के साथ विंडोज प्रदर्शन मॉनीटर का उपयोग करें। यदि .NET व्यवहार कर रहा है, लेकिन WPM कुछ तेज स्पाइक्स दिखा रहा है, तो शायद यह अप्रबंधित कोड में है। आप वास्तव में कुछ भी नहीं कर सकते हैं लेकिन आपके उपयोग पर, इसलिए शायद उस समय दस्तावेज़ पर वापस जाने का समय होगा।

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