2012-05-02 16 views
5

मैं सीओएस के साथ आईओएस प्रोजेक्ट पर काम कर रहा हूं। कार्यक्रम एक जुड़े वेबकैम से छवियों को कैप्चर करता है और इसे सॉकेट के माध्यम से आईफोन/आईपैड पर भेजता है। यह सब ठीक काम करता है और मैं डिवाइस पर अपनी स्ट्रीम को सफलतापूर्वक प्राप्त कर सकता हूं।प्रोग्राम निपटाने के बाद प्रोग्राम लटकता है()

लेकिन जब क्लाइंट डिस्कनेक्ट हो जाता है, तो वेबकैम बंद हो जाता है और इस फ़ंक्शन में, प्रोग्राम बस लटकता है। कोई त्रुटि संदेश नहीं और कोई अपवाद कॉल नहीं ... बस लटकता है! मेरा मानना ​​है कि यह कई धागे के साथ एक समस्या है लेकिन दुर्भाग्य से मैं समाधान खोजने के लिए सी # में अनुभवी नहीं हूं। मुझे आशा है कि किसी को यहाँ सही रास्ते पर मुझे ला सकता है ...

कोड:
onImageCaptured समारोह:

public void OnImageCaptured(Touchless.Vision.Contracts.IFrameSource frameSource, Touchless.Vision.Contracts.Frame frame, double fps) 
{ 
    _latestFrame = frame.Image; 
    Console.WriteLine("OnImageCaptured"); 
    if (isConnected) 
    { 
     Console.WriteLine("OnImageCaptured - isConnected"); 
     byteArray = new byte[0]; 
     MemoryStream stream = new MemoryStream(); 

     _latestFrame.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     stream.Close(); 
     byteArray = stream.ToArray(); 

     if (byteArray.Length > 0) 
     { 
      string eof = "<EOF>"; 
      byte[] eofByte = Encoding.ASCII.GetBytes(eof); 
      Console.WriteLine("OnImageCaptured - sendStream"); 
      this.onDataSend(byteArray); 
      this.onDataSend(eofByte); 
      stream.Flush(); 
     } 

     System.Diagnostics.Debugger.Log(0, "1", "\nByte Array Length: " + byteArray.Length.ToString()); 
    } 
    pictureBoxDisplay.Invalidate(); 
} 

कैमरा कक्षा में इस तरह परिभाषित किया गया है:

public event EventHandler<CameraEventArgs> OnImageCaptured; 

और शुरू हो रहा:

OnImageCaptured.Invoke(this, new CameraEventArgs(bitmap, fps)); 

तो यह फ़ंक्शन - मुझे विश्वास है - रन यूआई के बाद से एक अलग खतरा में अवरुद्ध नहीं कर रहा है जब छवियों में आ रहे हैं

तो अगली ग्राहक वियोग इस समारोह में नियंत्रित किया जाता है:।

public void onDataSend(byte[] data) 
{ 
    clientReady = false; 
    try 
    { 
     socketWorker.Send(data); 
    } 
    catch (SocketException se) 
    { 
     isConnected = false; 
     Console.WriteLine("Error: Data Write - SocketException"); 
     Console.WriteLine(se.ErrorCode.ToString()); 
     thrashOldCamera() // THIS FUNCTION HANGS THE PROGRAM !! 
     onDisconnectServer(); 

     // onDisconnectServer(); 
    } 
    catch (ObjectDisposedException) 
    { 
     isConnected = false; 
     Console.WriteLine("Error: Data Write - ObjectDisposedException"); 
     // onDisconnectServer(); 
    } 

} 

क्लाइंट डिस्कनेक्ट, thrashOldCamera() कहा जाता है। अभी तक ठीक काम करता है! अब:

private void thrashOldCamera() 
{ 
    Console.WriteLine("TrashOldCamera"); 
    // Trash the old camera 
    if (_frameSource != null) 
    { 
     try 
     { 
      _frameSource.NewFrame -= OnImageCaptured; 
      Console.WriteLine("TrashOldCamera - 1"); 
      _frameSource.Camera.Dispose(); // HERE IT HANGS. IT NEVER GOES PAST HERE !!! 
      Console.WriteLine("TrashOldCamera - 2"); 
      setFrameSource(null); 
      Console.WriteLine("TrashOldCamera - 3"); 
      pictureBoxDisplay.Paint -= new PaintEventHandler(drawLatestImage); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("End Trash Camera Ex: " + ex); 
     } 
    } 
    Console.WriteLine("End Trash Camera"); 
} 

प्रोग्राम _frameSource.Camera.Dispose(); पर लटकता है। जैसा कि ऊपर बताया गया है, कोई त्रुटि या अपवाद नहीं है। यह एक समस्या हो सकती है कि onDataReceive() को onImageCapture फ़ंक्शन() के भीतर बुलाया जाता है। मैंने फ़ॉर्म में एक बटन भी जोड़ा जो thrashOldCamera() ट्रिगर करता है और यह पूरी तरह से काम करता है।

किसी भी मदद/संकेतों की वास्तव में सराहना की जाती है।

+0

http://channel9.msdn.com/Series/-NET-Debugging-Stater-Kit-for-the- प्रोडक्शन- पर्यावरण/डिग्नोज़िंग - एप्लिकेशन- Issues-01 –

उत्तर

8

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

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

0

डिवाइस डिस्कनेक्ट होने पर ईवेंट को आमंत्रित करने के लिए खोजें। वहां वेब कैम को बंद करने के लिए कोड लिखें।

+0

हाय सक्षम करने की आवश्यकता हो सकती है गिजो, बिल्कुल यकीन नहीं है कि इसका मतलब क्या है? – Pascal

+0

ऐसी कोई घटना हो सकती है जिसका उपयोग आप वेब कैम को बंद करने के लिए कोड लिखने के लिए कर सकते हैं। हो सकता है कि आप नियंत्रण के साथ उपलब्ध घटनासूची की जांच कर सकें। – MACMAN

+0

तो मैंने अभी देखा है, कैमरा वर्ग में 'शून्य निपटान()' नामक एक फ़ंक्शन है। अगर मैं कैमरे को चालू करने के लिए बटन का उपयोग करता हूं - जो ठीक काम करता है - यह विधि ट्रिगर नहीं होती है। यदि कोई क्लाइंट डिस्कनेक्ट हो जाता है, तो यह इस प्रयोजन को – Pascal

3

यह नहीं पता कि यह वास्तव में एक टिप्पणी या उत्तर होना चाहिए, लेकिन कम से कम मैं आपको सही ट्रैक प्राप्त कर सकता हूं।

I found the source आपके द्वारा उपयोग की जा रही लाइब्रेरी में। यह वहाँ Camera.Dispose()

public void Dispose() 
{ 
    StopCapture(); 
} 

ठीक है, नहीं ज्यादा मदद की सामग्री, यहाँ है Camera.StopCapture()

internal void StopCapture() 
{ 
    _cameraMethods.StopCamera(); 
} 

फिर से एक, नहीं ज्यादा मदद है। _cameraMethodsCameraMethods का एक प्रकार है जो लाइब्रेरी WebCamLib से आता है जो प्रत्यक्ष शो के साथ संवाद करने के लिए एक सी ++ सहायक लाइब्रेरी है।

यहाँ CameraMethods::StopCamera()

void CameraMethods::StopCamera() 
{ 
    if (g_pMediaControl != NULL) 
    { 
     g_pMediaControl->Stop(); 
     g_pMediaControl->Release(); 
     g_pMediaControl = NULL; 
    } 

    g_pfnCaptureCallback = NULL; 

    if (g_pIBaseFilterNullRenderer != NULL) 
    { 
     g_pIBaseFilterNullRenderer->Release(); 
     g_pIBaseFilterNullRenderer = NULL; 
    } 

    if (g_pIBaseFilterSampleGrabber != NULL) 
    { 
     g_pIBaseFilterSampleGrabber->Release(); 
     g_pIBaseFilterSampleGrabber = NULL; 
    } 

    if (g_pIBaseFilterCam != NULL) 
    { 
     g_pIBaseFilterCam->Release(); 
     g_pIBaseFilterCam = NULL; 
    } 

    if (g_pGraphBuilder != NULL) 
    { 
     g_pGraphBuilder->Release(); 
     g_pGraphBuilder = NULL; 
    } 

    if (g_pCaptureGraphBuilder != NULL) 
    { 
     g_pCaptureGraphBuilder->Release(); 
     g_pCaptureGraphBuilder = NULL; 
    } 

    this->activeCameraIndex = -1; 
} 

है ऐसा प्रतीत होता है अपने अपवाद प्रबंधित सीमा के मूल निवासी के दौरान खाया जा रहा है।मुझे नहीं पता कि यह आपकी मदद करेगा लेकिन कम से कम यह आपको कहां देखना है इसकी शुरुआत देता है।

अप्रबंधित कोड डीबगिंग सक्षम करें और देखें कि क्या आप पुस्तकालय स्रोत के माध्यम से कदम उठा सकते हैं और देख सकते हैं कि वास्तविक समस्या कहां है।

enter image description here

मैं इस एक समुदाय विकी अगर जो सी ++/सी # इंटरॉप के साथ और अधिक अनुभव है किसी और को इस संपादित करें और क्या इस मुद्दे को डिबग करने के लिए आगे क्या करना है के और अधिक जोड़ने के लिए करना चाहता है बनाने रहा हूँ।

+0

हैलो स्कॉट। आपके उत्तर के लिए Thx। यह निश्चित रूप से वहां कहीं तोड़ता है लेकिन समाधान खोजने के लिए यह मेरे दृश्य सी # - सी ++ स्तर पर है। मुझे लगता है कि मुझे एक और वेबकैम स्क्रिप्ट देखना है जो प्रत्यक्ष शो का उपयोग नहीं करता है। – Pascal

0

शायद ज़रुरत पड़े इसके साथ अभी भी एक मुद्दा है वहाँ, कैमरे से डिस्कनेक्ट करने के लिए करता है, तो फिर तो करना चाहते हैं तो आप भी Touchless.CurrentCamera.Dispose जोड़ सकते हैं Touchless.RefreshCameraList का प्रयोग करें। आपको अभी भी अप्रबंधित कोड डिबगिंग

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