Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. What queuing technique and GUI component should I choose for my multi-comport, receive-only terminal software?

What queuing technique and GUI component should I choose for my multi-comport, receive-only terminal software?

Scheduled Pinned Locked Moved C#
csharpvisual-studiowpfcombusiness
20 Posts 6 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • OriginalGriffO OriginalGriff

    That's why I wouldn't use the event at all, but put each SerialPort in into own thread, continually monitoring (or perhaps sleeping / checking depending on how accurate you need your timestamps). That way, your system uses as many cores as it has to receive the data, and you can queue the results into a (lower priority if necessary) UI thread to handle display. The timestamps are a message function, so you assemble that as a package with the whole message, and pass that on. BackgroundWorker is great for that as it includes the UserState object as part of the Progress reporting mechanism which is routed direct to the UI thread. This ensures independence of your serial ports, and if you have enough cores very low latency for the message / timestamp itself.

    "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

    A Offline
    A Offline
    arnold_w
    wrote on last edited by
    #11

    I'm happy with the solution of using event driven processing, this is a quick-and-dirty piece of software I will need asap (or preferably, yesterday) so I think it's overkill to have separate threads polling SerialPort.BytesToRead. But are you saying that if I create the SerialPort objects in separate threads, then it will be possible for the PC to execute the following events handlers simultaneously: COM1port_DataReceived, COM2port_DataReceived, COM3port_DataReceived, etc?

    OriginalGriffO 1 Reply Last reply
    0
    • A arnold_w

      I'm happy with the solution of using event driven processing, this is a quick-and-dirty piece of software I will need asap (or preferably, yesterday) so I think it's overkill to have separate threads polling SerialPort.BytesToRead. But are you saying that if I create the SerialPort objects in separate threads, then it will be possible for the PC to execute the following events handlers simultaneously: COM1port_DataReceived, COM2port_DataReceived, COM3port_DataReceived, etc?

      OriginalGriffO Offline
      OriginalGriffO Offline
      OriginalGriff
      wrote on last edited by
      #12

      I have no idea - I've never tried, and I'm really not sure how I would test it ... :laugh: I would doubt it: if all the DataReceived events are set up by the same thread, then the code to kick the actual event off will all be executing on that thread (though the handler itself will be executed on a new thread / pool thread) so there will be some delay introduced there. I also suspect that the actual serial port char received interrupt goes through many layers of software before it even gets to the SerialPort class and then be routed to the right thread to kick of the Event. When I need multiple sources, I prefer to use separate threads and poll instead of use Events as it's rather more "immediate".

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

      A 1 Reply Last reply
      0
      • OriginalGriffO OriginalGriff

        I have no idea - I've never tried, and I'm really not sure how I would test it ... :laugh: I would doubt it: if all the DataReceived events are set up by the same thread, then the code to kick the actual event off will all be executing on that thread (though the handler itself will be executed on a new thread / pool thread) so there will be some delay introduced there. I also suspect that the actual serial port char received interrupt goes through many layers of software before it even gets to the SerialPort class and then be routed to the right thread to kick of the Event. When I need multiple sources, I prefer to use separate threads and poll instead of use Events as it's rather more "immediate".

        "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

        A Offline
        A Offline
        arnold_w
        wrote on last edited by
        #13

        OriginalGriff wrote:

        I would doubt it: if all the DataReceived events are set up by the same thread

        No, I wouldn't do that, I would create my SerialPort objects and hook up the DataReceived events in separate threads.

        OriginalGriffO 1 Reply Last reply
        0
        • A arnold_w

          OriginalGriff wrote:

          I would doubt it: if all the DataReceived events are set up by the same thread

          No, I wouldn't do that, I would create my SerialPort objects and hook up the DataReceived events in separate threads.

          OriginalGriffO Offline
          OriginalGriffO Offline
          OriginalGriff
          wrote on last edited by
          #14

          That's just adding a further layer of abstraction - the DataReceived event is fired on a pool thread, not the original starter thread, so ... :-D

          "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

          "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
          "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

          A L 2 Replies Last reply
          0
          • OriginalGriffO OriginalGriff

            That's just adding a further layer of abstraction - the DataReceived event is fired on a pool thread, not the original starter thread, so ... :-D

            "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

            A Offline
            A Offline
            arnold_w
            wrote on last edited by
            #15

            So you're saying it's not a good idea? How many pool threads does a PC have? Can I somehow dictate what pool thread the different Com ports should issue events onto?

            OriginalGriffO 1 Reply Last reply
            0
            • OriginalGriffO OriginalGriff

              That's just adding a further layer of abstraction - the DataReceived event is fired on a pool thread, not the original starter thread, so ... :-D

              "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #16

              I need to peel potatoes but I don't want to use a potato peeler.

              It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

              P 1 Reply Last reply
              0
              • A arnold_w

                So you're saying it's not a good idea? How many pool threads does a PC have? Can I somehow dictate what pool thread the different Com ports should issue events onto?

                OriginalGriffO Offline
                OriginalGriffO Offline
                OriginalGriff
                wrote on last edited by
                #17

                arnold_w wrote:

                How many pool threads does a PC have?

                Depends: Thread Pools - Win32 apps | Microsoft Docs[^]

                arnold_w wrote:

                Can I somehow dictate what pool thread the different Com ports should issue events onto?

                No. It's a pool. As an when a thread is needed, one is pulled from the pool and started.

                "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

                "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                1 Reply Last reply
                0
                • L Lost User

                  I need to peel potatoes but I don't want to use a potato peeler.

                  It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                  P Offline
                  P Offline
                  Peter_in_2780
                  wrote on last edited by
                  #18

                  You haven't got a swiss army knife?

                  Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

                  L 1 Reply Last reply
                  0
                  • P Peter_in_2780

                    You haven't got a swiss army knife?

                    Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #19

                    I do! ... But I don't want to use it because it might do the job. :doh:

                    It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                    1 Reply Last reply
                    0
                    • A arnold_w

                      I have a number of devices with Com ports (UART:s running at MBaud speeds) that I need to monitor and make sense of. The devices send ASCII-strings with information about what's going on and I need to log this information on the screen row-by-row as the strings arrive (one row per port_DataReceived event). I would also like to get a timestamp when each string arrives and log the timestamp in the leftmost part of the row and the time elapsed since previous row just to the right of the timestamp. The following requirements apply: a) The GUI must have a checkbox with the text "Auto-scroll". When unchecked, I should be able to scroll among the already written rows. b) The GUI must have a "Clear Log Window" button, which clears the log the window when pressed, even if data logging is ongoing (of course, the very next microsecond after the button is pressed, new data has arrived and will be put in the first row again). c) The bulk of the code must be written in C# (with no WPF). However, simple event handlers, such as button event and checkbox-changed handlers, with very little code inside them are ok in other langugages as well. d) Must show the data in columns that can easily be read, either in a table or something supporting equal width characters (e.g. Courier New font). e) If it's not Excel, then it should easy to copy-and-paste into Excel for further in-depth analysis. f) The timestamp should be as accurate as possible, i.e. I want to exit the interrupt routines asap in order to not block interrupts from other Com port. g) Must be able to show text in different colors. h) Must be able to show more than 65535 characters. My questions are: A. What queuing technique should I use to ensure that I stay as little times as possible in the port_DataReceived(object sender, SerialDataReceivedEventArgs e) event handler? Can I use a simple backgroundWorker (Threading in C# - Part 3 - Using Threads[^], basically queuing addRowToLogWindow-tasks) or is there a faster/better approach? B. What GUI component should I use to display the data in? I've considered the following: 1. Directly in the Visual Studio Output window: I don't know how to implement the "Auto-scroll" checkbox and "Clear Log Window" button. Also, there seems to come other unwanted data in this window as well (exceptions, threads are te

                      L Offline
                      L Offline
                      Luc Pattyn
                      wrote on last edited by
                      #20

                      Hi, here are my suggestions: 1. use a single BackGroundWorker per COM port; use its progress reporting facility to report displayable results. 2. Use synchronous read operations, thus avoiding the tricky DataReceived event. If you are lucky and the peripheral reports text messages ending on some specific terminator, use ReadLine(); when necessary, adjust the NewLine property to equal that terminator. If not, just use Read and have the BGW discover the beginning and end of every message. 3. For the UI use the simplest List oriented Control that satisfies your interactive requirements; a ListView is good, however I prefer a ListBox. 4. Define a little class holding the raw data of one displayable result. That is one object, no more expensive than the array a ListView would need. Instances of this class, not strings, are to be added to the ListBox Items collection. 5. Make the ListBox ownerdrawn, giving it a fixed ItemHeight, and an appropriate DrawItem handler that takes care of horizontal positioning, coloring, and whatever fancy styling you may want. That's it; and it is bound to be simpler than the code you probably are experementing with right now... :)

                      Luc Pattyn [My Articles] If you can't find it on YouTube try TikTok...

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups