Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Threading with ResetEvent and SerialPort problem

Thread Threading SerialPort AutoResetEvent ManualResetEvent WaitHandle

  • Please log in to reply
2 replies to this topic

#1 Hachi'

Hachi'

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationEurope

Posted 04 November 2013 - 08:20 PM

Hello, I'm interfacing a device via SerialPort. The device will send a response immediately after sending some bytes to the device. Therefore I want a SPI-style WriteRead-Method, which sends some bytes, reading and returning the response-bytes. I'm trying to achive this with the AutoResetEvent class and the DataReceived event. The WriteRead-Method sends some bytes to the device, blocks the call until receiving a response, using AutoResetEvent.WaitOne and AutoResetEvent.Set.
public Byte[] WriteRead(Byte[] bytesToSend){    this.FrameReceived += Device_FrameReceived;    this.Write(bytesToSend); // Send bytes to the device    Boolean signaled = this.autoResetEvent.WaitOne(); // Wait for response (FrameReceived event)    this.FrameReceived -= Device_FrameReceived;    if (signaled)    {        return this.incomingBytes;    }    else    {        return null;    }}
After receiving the bytes, AutoResetEvent.Set is called, to unblock the WriteRead-Method.
private void Device_FrameReceived(Object sender, FrameReceivedEventAgs e){     this.incomingBytes = e.Frame;     this.autoResetEvent.Set();}
The code above works if it's executed before Thread.Sleep is called in the Main-Method. If the code is executed after Thread.Sleep, the code doesn't work. Device_FrameReceived is never called.
public static void Main(){    device = new Device();    device.FrameReceived += device_FrameReceived;     // This will work, because Thread.Sleep isn't called    // Byte[] bytes = device.WriteRead(bytesToSend);    Thread.Sleep(Timeout.Infinite);}private static void device_FrameReceived(Object sender, FrameReceivedEventAgs e){    // This won't work, beacause Thread.Sleep is already called    Byte[] bytes = device.WriteRead(bytesToSend);}
I attached a sample application which demonstrates the problem, maybe someone is willing to explain me the problem and how to solve it.

Attached Files



#2 perpetualKid

perpetualKid

    Member

  • Members
  • PipPip
  • 20 posts

Posted 04 November 2013 - 09:45 PM

your code looks correct, I would have implemented it in a similar way.

 

However I feel that Thread.Sleep(Timeout.Infinite) on the main thread just renders my devices unusable, both in a way that interrupt handler and other code not executed anymore, but also that am not able to attach a debugging session or deploy new code and I need to use MFDeploy to erase the current deployment before I can use the device again. Happens both on a N1 and a N2 device with latest stable firmware, so at least for now I've replaced the infinite sleep with some arbitrary sleep timeout depending bit on the scenario, 200-1000ms, and not seeing the issues anymore.

Not sure what's going wrong and if other seeing same behavior, but haven't spent time yet diving into the device's firmware code.



#3 Hachi'

Hachi'

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationEurope

Posted 06 November 2013 - 06:06 AM

Thanks, for watching through my code.

 

Normally, Thread.Sleep(Timeout.Infinite) works fine, I never had such problems you described.







Also tagged with one or more of these keywords: Thread, Threading, SerialPort, AutoResetEvent, ManualResetEvent, WaitHandle

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.