✅ Correct way to pass data between threads?
I have an event on a simple Winform reading from the serial port. The issue is I would like to output the data onto a winform component, but because its on an even it happens on a different thread and I get the error
Cross-thread operation not valid: Control 'textBoxRecieve' accessed from a thread other than the thread it was created on.
so what is the correct way to pass this data? I know I could do something like a channel do make a cross thread communication system, but that seems excessive and I figure there is an easier way I do now know
That was the function running and erroring. I was just trying to make a simple ECHO test
debugListen.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
and that is how I was setting up the event51 Replies
gui framework usually provide a dispatcher
for winforms thats
Control.Invoke
Am i changing my event to be called from the invoker or am I adding the invoke method to my handler function? not really sure how this works so just trying to understand
either would work
but id probably do that from the handler
i was gonna say changing the handler function seems easier
This works. Thank you. Posting code incase anyone else finds this later
I do have a question. how does the Invoke method work?
Is it telling the main thread to pause what its doing and run this code now? or is it some other way?
the ui thread has something like an internal list for delegates, which it will process on each iteration.
basically something like
btw u dont need the delegate, u can simply use
Action<T>
for that
and u should prepare the data in ur handler and only pass that then:
that makes sense.
is there a reason to do the if() instead of just casting it? shouldnt it always be a SerialPort
hmmm, actually in this case probably not, as it should crash if the sender isnt a
SerialPort
to show its a bug, i guess
or do the pattern matching and throw a more meaningful exception in the else branchalso im guessing I should prepare data before i use it since its on its own thread already?
yeah, u want to do the minimum amount of work on the ui thread
else it might freeze if there is too much going on
ok this is a bit off topic, but im not sure if there is a better way to do this.
Is there a better way to identify data coming from the serial port?
Currently im just sending formated strings and parsing them
btw thanks for all the help this makes alot more sense now. Thought i would ask this question though since there might be a better way to do communication
tbh i have no clue about how serial ports work,
the first thing that catches my eye is the question if the data is always one complete message, or if it could also be multiple messages at once or even fragmented messages
or maybe its fragmented because the connection died
such cases arent handled at all right now
thats very true. but that would be handled on the slave device
This is for a system of pi picos talking with each other making a tracking system for a rocket. this UI is for a ground station so that handling would be for the pico attached to it to group the message, but you are right I should still add a catch incase a message fragments
serial port doesn't have the concept of message, it's just data
although there are some settings that can influence this
the parsing itself could be done via regex as well, would be a bit cleaner
I have done next to 0 work with regex. I know it exists and i have used it in path of exile(a game) and thats it
so its just stream based, so it it can be multiple and/or partial data at once
yeah
I have a virtual serial port rn to test with
It is just sending raw bytes
as it recieves them it puts them in the next port (in the case of my virtual com)
do the picos send some kind of marker for an end of a message?
yes, from the pov of c# it's the usual stream reader, so you say read 2000 bytes or even read 1 byte
and when it's ready it returns that to you
no clue I am getting my picos tomorrow to start testing. I was planning on adding a separation byte incase i send longer messages
that way i can just
data.split('~')
you could search if pico offers flow control settings or something
but in the end who cares
yeah thats too much work for a system that maybe will recieve 100 messages a second
i dont think i will be overflowing a pico or the serial communication line
what 1000/sec?
1000 bytes/sec you mean
extra 0
100/sec
it could get around 20 or 30 updates from each tracker a second
each tracker is sending 3 doubles
so ~800 bytes
its using 115200 baud so its good for 14400 bytes
baud is bit/s, not byte
ah im still well over
eh you know it's still relatively busy for a serial
u know this would be a lot easier if the protocol would be binary instead of text based 😂
thats what testing is for.
are you sure?
binary could be a mess
text is somewhat easier
this guy just wants to use bit banging for everything
why would it be a mess?
i would say its a lot easier, the only real trap would be difference in endianness, which can be easily covered
I believe on the lower level serial is just hex so its not too different. its just readable
text is easier because human understandable
and debuggable
almost every protocol i met was text based
SPI is not i believe
probably it's like that because it's meant to be operated by a console or somethings
i2c is also only hex i believe
but i dont know enough about them to advocate one way or another
iot for home automation is text
what protocol does home automation use?
openwebnet
is one of them
well it makes sense. Alot of that data is probably outputting to the user so sending strings and chars vs hex makes sense
i don't exactly know what made them take this route
well this derailed quite a bit form the original question. Thanks for all the help, I'll look into different ways to parse and setup my communication network
good luck 😄
also please dont forget to $close the thread (if u have questions later it would be better to open a new thread anyway)
Use the
/close
command to mark a forum thread as answeredto me if you have that amout of updates you could use a queue (buffer) between serial and ui
just that
wouldnt really be a queue. because I want the newest information as soon as possible. If im getting too many inputs I just throwout the ones i miss
will do
If i need to throttle it. i just ignore inputs read the newest ones and disregard the rest
sure sure, i was just thinking on how to do this in a non async/await architecture
you would still need a timeout for the response from the form/controls
ah i see. Well the input for this is a pi pico, the pico only runs C so it will be bare bones. I believe any modern laptop should be able to handle the through put of a pi, but i could be wrong
the pi is the place where i except a bottleneck to be if there even is one
Aight ima close this now. I have to go to work. Ty for the help