2013-05-05 8 views
0

Form1에 단추와 텍스트 상자가 있습니다. 버튼을 클릭하면 USB 장치에서 일부 데이터를 가져와야합니다. 웬일인지 정확히 2 % 만 제대로 작동합니다 (100 회 클릭 중 2 번 응답을 얻을 수있었습니다).dll에서 Asynccallback이 발생하면 양식이 고정됩니다.

namespace Test_onForm1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Lib1.FindHID.TransferInputAndOutputReports(0xC0); //request specific data from USB device 
     } 
    } 
} 

USB 통신을 처리하는 코드는 DLL LIB1이다 (아래의 코드 단편) :

namespace Lib1 
{  
    public static class FindHID 
    { 
    private static void TransferInputAndOutputReports(UInt16 repType) 
    { 
     //some code here sending request to USB device... and then read what came from USB 
     ReadInput(); 
     //some code here     
    }  

    // Read an Input report. 
     private static void ReadInput() 
     { 
      Byte[] inputReportBuffer = null; 
      inputReportBuffer = new Byte[MyHid.Capabilities.InputReportByteLength]; 
     IAsyncResult ar = null; 

      if (fileStreamDeviceData.CanRead) 
     { 
     // RUNS UP TO THIS POINT and then Form1 freezes most of the time 
       fileStreamDeviceData.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, new AsyncCallback(GetInputReportData), inputReportBuffer);     
      } 
     } 

    private static void GetInputReportData(IAsyncResult ar) 
     { 
     // RARELY GETS HERE 
       Byte[] inputReportBuffer = null; 
       inputReportBuffer = (byte[])ar.AsyncState;    

    fileStremDeviceData.EndRead(ar); //waits for read to complete 
     // then code to update Form1 
    }  
    } 
} 
} 

가 작동하지 않는 것이 fileStreamDeviceData 주위 중지 여기서 는 Form1의 코드 .BeginRead 및 Form1 고정합니다.

테스트를 위해 완전히 새로운 프로젝트를 만들었고 DLL 대신 모든 DLL 코드를 Form1에 복사했습니다. 이 옵션은 100 % 완벽하게 작동합니다. 내 질문에 DLL로 작동하지 않는 이유는 무엇입니까?

업데이트 : 운이 좋으면 작동이 시작되어 응용 프로그램을 종료 할 때까지 무기한으로 작동합니다. 그런 다음 다시 작동하도록 노력해야합니다. 이 문제를 해결하는 방법?

+0

아마도 'inputReportBuffer.Length' 때문에 더 많은 바이트를 읽을 수 있습니다. 사용 가능한 바이트보다 많습니다. 어떤 타입이'fileStreamDeviceData'이고'Available' 속성을 가지고 있습니까? – Silvermind

+0

바이트 수는 정확합니다. 이 프로그램은 완벽하게 잘 작동하는 원본 프로그램의 복사본입니다. 나는 여기서 아무 것도 변하지 않았다. 내가 한 유일한 방법은 코드의 일부를 새로 생성 된 DLL로 옮기는 것입니다. 아이디어는 자신의 필요에 따라 자신의 응용 프로그램을 만들 수 있도록 DLL을 내 친구에게 배포한다는 것입니다. – mike5ocns

+0

fileStreamDeviceData는 private static FileStream이며 .Available 속성을 가지고 있지 않습니다. – mike5ocns

답변

0

대부분 문제는 EndRead의 코드가 양식을 업데이트하려고하지만 UI 스레드가 아니라는 것입니다. Form.Invoke을 수행하거나 UI 스레드가 업데이트를 수행 할 수 있도록 데이터가 준비되었음을 알리는 방법으로 UI 스레드와 동기화해야합니다.

+0

위임자를 통해 UI 업데이트가 있습니다 (위의 코드는 단순화되지 않았습니다). 디버깅을 위해 코드를 기본 최소값으로 제거했습니다. – mike5ocns

+0

내가 코멘트를 보는 곳 : // 여기 RARELY가 지금 당장 나에게 Console.Writeline이있다 ("여기에 도착합니까?"); 콘솔에서이 표시가 보이지 않습니다. 나는 행운이 나서 모든 일을하면 나타날 것입니다. – mike5ocns

0

솔트!

Microsoft 웹 사이트에서 찾을 수 : "스트림에서 BeginRead의 기본 구현은 Read 메서드를 동 기적으로 호출합니다. 즉, 일부 스트림에서 Read가 차단 될 수 있습니다."

Visual Studio 2010에서 .NET Framework 4.0을 사용하고있었습니다. 대신 Stream.ReadAsync 메서드가있는 .NET Framework 4.5로 업데이트하기로 결정했습니다. 그러나 Visual Studio 2010에 Stream.ReadAsync을 구현할 수 없었습니다 (그 이유를 모르거나 2012 년에 업데이트해야 할 수도 있습니다). 업데이트 된 Framework 4.5를 사용하여 코드를 시험했으며 항상 작동합니다.

+0

저를 도와 주신 것에 대해 감사드립니다! – mike5ocns