Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7897385
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T08:09:12+00:00 2026-06-03T08:09:12+00:00

I have C# multithreaded application that has to interface with a hardware using SerialPort.

  • 0

I have C# multithreaded application that has to interface with a hardware using SerialPort.

The program is mostly command response sequence but the hardware can send an unsolicited “RESET” message due to an internal error at which time the software has to reinitialize it by sending a sequence of commands setting certain values.

More than one thread (from threadpool) can try to do a TakeSampleNow()

public class ALComm
{
    private readonly AutoLoaderManager _manager;
    private readonly AutoResetEvent dataArrived = new AutoResetEvent(false);
    private SerialPort _alPort;
    private string _alResponse;

   .... Code to init _alPort and attach datareceived event etc

   public void TakeSampleNow()
    {
        if (Monitor.TryEnter(_alPort, 1000)) //let's wait a second
        {
            _manager.MessageList.Enqueue("Try sampling");
            try
            {
               Send("Command1");
               string response = Receive();

               switch(response)
                {
                   case "X": blah blah..
                   case "Y": blah blah..
                } 

               Send("Command2");
               string response = Receive();

               while(response != "OK")
                 {
                   Send("Command3");
                   string response = Receive();
                   Send("Command2");
                   string response = Receive();
                 }
            }
            finally
            {
                Console.WriteLine("Releasing port");
                //Thread.CurrentThread.Priority = ThreadPriority.Normal;
                Monitor.Exit(_alPort);
            }
        else
        {
            _manager.MessageList.Enqueue("Port is busy!!!");
        }
   }

    public string Receive()
    {
        string inString = null;

            dataArrived.WaitOne(1000);
            inString = _alResponse;

        return inString;
    }

    private void AlPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        _alResponse = _alPort.ReadLine();

        //if (_alResponse.ToUpper().Contains("RESET"))
        //{
        //    _alState = AlState.Reset;
        //    TryInitialize();
        //}

        dataArrived.Set();            
    }

    private void TryInitialize()
    {
        Monitor.Enter(_alPort);       //lock so other threads do not access samplenow during initialization
        try
        {
            string response;

            Console.WriteLine("Initializing ... The AutoLoader");
            _alPort.DiscardInBuffer();

            Send("CommandX");
            response = Receive();

            --- blah blah

           _alResponse = "";
        }
        finally
        {
            Monitor.Exit(_alPort);
        }
    }

I can check the response in the datareceived event and wait on lock in TryInitialize() and for other threads in TakeSampleNow to release the lock, I would have to check on each response if _alResponse contains “RESET” and if it does return from the method. Which makes it more convoluted.

Any suggestions of how I can do this better. I believe it can be a state machine but am not able to conceptualize it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T08:09:13+00:00Added an answer on June 3, 2026 at 8:09 am

    You don’t supply much details of your protocol – you don’t say if command/rsponse pairs can overlap and, if so, how the responses are matched up with the commands.

    You should be able to do this with a state-engine. Run the state-machine with its own thread that waits on a BlockingCollection for events. You will need a ‘SerialRecv’ thread as well to run your protocol and parse incoming bytes into messages.

    I would use just one ‘SerialEvent’ class to carry events into the SM queue. The class should have an enum to describe the event and members for rx buffer, txData, parsed data, data to assemble tx string from, an exception/errorMess field – everything needed for any event or and forward purpose, (eg. the SM might forward a completed Request/Response to a display or logger).

    Some events I can think of straightaway: EsmNewRequestResponse,EsmRxData,EsmResetRx

    The event enum may, as some stages, have other values that are not used by the SM, eg: EsmError,EsmLog,EsmDisplay.

    If you need timeouts, you can generate one by timing out the take() on the SM input queue.

    Yes, there are things I left out.

    If several threads issue SerialEvent instances ‘at once’, the SM will get new SerialEvents while it is still processing the first one. The SM will need another queue/deque to hold the SerialEvents awaiting handling. Due to the serializing of the SM by the BlockingCollection/thread, this ‘pending’ queue does not have to be thread-safe. The SM should check this pending queue after any request/response has completed to see if there is another one to process.

    To handle request/response synchronously from several threads, the requesting threads must have smething to wait on. An AutoResetEvent in the SerialEvent class would do. Submitting a SerialEvent to the system would queue up the SerialEvent instance and wait on the AutoResetEvent. When the processing of the instance is complete, (ie. response received, error or timeout), the SM would set the event and the originating thread would run on with its SerialEvent instance filled in with data.

    Next – the SerialEvent class is getting towards the point where it may be better to pool them rather than continually create/CG. That would need another BlockingCollection to act as the pool.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a multithreaded application that has many concurrent operations going on at once.
I have developed a multithreaded web application that runs in Tomcat. But I cannot
I have a multithreaded application that is using LinqToSql. One of the things I
I have a multithreaded WPF application that is using > 600 threads after is
AI have a WF 4 application which contains a sequence workflow that has a
I have a multithreaded application that runs using a custom thread pool class. The
I have a multithreaded application that makes heavy use of OpenSSL in C. It
In a multithreaded application. I have a bunch of function that loop through a
I have a multithreaded application. However I noticed, I'm using OpenGL and this should
I have a multithreaded Windows application where one of the threads has a message

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.