Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Dear all

I have a communication class which does use SerialPort to communicate. My first implementation polled the port and was very efficient. Because I hate polling I tried to replace it.

My idea:
- I hook into SerialPort.DataReceived. DataReceived will be called from a the SerialPort thread
- My DataReceived checks the condition and set an AutoResetEvent to signaled if the condition meats the criterion
- The main thread waits using AutoResetEvent.WaitOne().

Problem:
Even while DataReceived signales AutoResetEvent, the main thread freezes.

Thanks in advance.
Regards


code fragments:
C#
class CommunicationDeviceSerialPort : CommunicationDevice
{
  System.IO.Ports.SerialPort  serialPort  = new System.IO.Ports.SerialPort();
  AutoResetEvent              recSynchObj = new AutoResetEvent(false)
	
  // Hook for SerialPort.DataReceived. Called by the SerialPort receiver thread
  private void SerialDataReceivedEvent(object sender, SerialDataReceivedEventArgs e)
  {
    // Acoording to MSN docu, this will be called from a background thread


    // read in pending SerialPort data into deviceBuffer
    ... deviceBuffer

    // Check condition
    if (deviceBuffer meats my condition)
       recSynchObj.Set();
  }

  // Communicate will be called from the main thread 
  public int Communicate(String Command, int TimeoutMS, out Data)
  {
    // Some Cleanup
    ...

    // Send the command
    serialPort.Write(Command);

    // Ininite timeou for tests
    bool xSignaled= recSynchObj.WaitOne();  

    //************************************
    //****It never comes out of WaitOne one line above. Why???*****
    //************************************

    if (xSignaled)
    {
        // Read data from devicebuffer
        ...
    }

    // With Progress in final version
    /*
    while(true)
    {
      bool xSignaled= recSynchObj.WaitOne(250);
      if (xSignaled)
      {
        // Read data from devicebuffer
        ...
        break;
      }
      // ShowProgress();
      // CheckTimeout()
    }
    */
  }
}


C#
class FormMain
{
  CommunicationDevice commDevice= new CommunicationDeviceSerialPort();

  private void DoCommunicate
  {
    // Send somthing
    commDevice.Communicate(cmd, 2000, );	
  }	
}
Posted
Updated 13-Jul-12 4:24am
v2

1 solution

Don't wait on the main thread. That can cause the message pump to be completely blocked and that means WaitHandles never get the notification that they're done through to the application, as well as locking the UI.
 
Share this answer
 
Comments
[no name] 13-Jul-12 17:51pm    
Hello BobJanova
Thank you very much for your reply; it makes sense what you write.
Seems to be a big difference compared to native WIN Application.
Regards

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900