0

I have a form Form1 with a button and text box. When I click on the button I should get some data from USB device. For some reason it works correctly only about 2% (I was able to get 2 correct responses out of 100 clicks). Here is the code for the Form1:

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
        }
    }
}

The code handling USB communication is in DLL Lib1 (fragments of the code below):

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 
     }      
    }
 }
}

When it doesn't work it stops around fileStreamDeviceData.BeginRead and then Form1 freezes.

For testing I created a completely new project and instead of using a DLL I copied all DLL code to the Form1. This option works perfectly fine 100% of the time. So my question is why it doesn't work with DLL?

Update: when I get lucky and it start working then it works indefinitely until I close application. Then, I have to keep trying to get it to work again. How to troubleshoot this problem?

mike5ocns
  • 1
  • 1
  • Perhaps you are reading more bytes because of `inputReportBuffer.Length` than there are bytes available. What type is `fileStreamDeviceData` and does it have an `Available` property? – Silvermind May 05 '13 at 14:34
  • The number of bytes is correct. This program is a copy of my original program that works perfectly fine. I didn't change anything here. The only thing I did is to move part of the code to a newly created DLL. The idea is that I will distribute DLL to my friends so they can create their own application based on their needs. – mike5ocns May 05 '13 at 16:23
  • The fileStreamDeviceData is private static FileStream and doesn't have .Available property – mike5ocns May 05 '13 at 16:25
  • I updated the code above as I forgot to show fileStreamDeviceData.EndRead(ar); – mike5ocns May 05 '13 at 16:53
  • And you're certain that `CanRead` is returning `true`? If the file is closed, `CanRead` returns `false`. – Jim Mischel May 05 '13 at 17:14
  • Yes, CanRead returns true, but right after .BeginRead all freezes like it's waiting for callback to fire up but for some reason it doesn't. – mike5ocns May 05 '13 at 18:22

2 Answers2

0

Most likely the problem is that the code in EndRead is trying to update the form, but it's not on the UI thread. You have to synchronize with the UI thread, either by doing Form.Invoke or some way notifying the form that the data is ready so that the UI thread can do the update.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • I have that UI update thru delegate (not shown in the above code for simplicity). I stripped the code to the basic minimum for debugging. – mike5ocns May 05 '13 at 17:08
  • I the place where you see comment: // RARELY GETS HERE right now I have Console.Writeline ( " Do it get here? "); and I don't see this showing in console. It will show up when I get lucky and then all work. – mike5ocns May 05 '13 at 17:10
0

SOLVED!

Found on Microsoft website: "The default implementation of BeginRead on a stream calls the Read method synchronously, which means that Read might block on some streams."

I was using .NET Framework 4.0 on Visual Studio 2010. Decided to update to .NET Framework 4.5 which has Stream.ReadAsync method instead. However, I couldn't implement Stream.ReadAsync on Visual Studio 2010 (don't know the reason, maybe needs update to 2012?). So, with updated Framework 4.5 I tried my code and it works ALL THE TIME EVERY TIME.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
mike5ocns
  • 1
  • 1