Jump to content

C# multi-threading, multi-form madness!

Curious Pineapple

I'm writing an application in C# using Windows Forms. I have a set of physical buttons that are connected through a serial interface, and a string of bytes are sent to indicate button presses.

 

The problem I am facing is that I need the thread that handles the serial data to work out which form has focus and then invoke an action on that form, and pass along the byte array of received data. I have this working already between the worker thread and the form that created it, it waits for the 16 bytes of serial data to arrive, then invokes a function on the main form and the byte array gets passed along fine. I have also created another form for testing, and that works fine too, if hard coded. Form 1 creates a thread that's just looping and waiting for serial data, and I have it invoking actions on Form 2 just fine. I'm not actually using names like Form1, Form2 etc.

 

I'm thinking of having a global string that forms modify in their _load, and the serial thread uses a switch statement to invoke actions on the correct form, but that seems a rather long winded way to do things.

 

Is there a way to use something like Application.OpenForms to get a list of forms, check which one has focus then invoke the serial processing routine on that form using the form name in Application.OpenForms? I am thinking more towards it not being possible as it could potentially try and run a function that doesn't exist, but not being a C# expert, I'm treading into the unknown.

Link to comment
Share on other sites

Link to post
Share on other sites

Can you use events? When an event is triggered, any forms that are subscribed to the events can check if they are in focus and if they are, run the required code.

Link to comment
Share on other sites

Link to post
Share on other sites

I've began to re-design the interface. I was using multiple forms to ensure that user-entered data and stored data was destroyed when the form was disposed. I'm going to use a single form with programmatically generated user controls and every user session will have it's data stored in a class that will be disposed when it's finished with. Gives me more options with different screen resolutions too :)

Link to comment
Share on other sites

Link to post
Share on other sites

18 minutes ago, Curious Pineapple said:

I've began to re-design the interface. I was using multiple forms to ensure that user-entered data and stored data was destroyed when the form was disposed. I'm going to use a single form with programmatically generated user controls and every user session will have it's data stored in a class that will be disposed when it's finished with. Gives me more options with different screen resolutions too :)

Sounds like a good idea to me.

Link to comment
Share on other sites

Link to post
Share on other sites

17 hours ago, Curious Pineapple said:

I've began to re-design the interface. I was using multiple forms to ensure that user-entered data and stored data was destroyed when the form was disposed. I'm going to use a single form with programmatically generated user controls and every user session will have it's data stored in a class that will be disposed when it's finished with. Gives me more options with different screen resolutions too :)

16 hours ago, madknight3 said:

Sounds like a good idea to me.

Agreed, I also think that you've done the right thing. It seems that you have naturally came to the conclusion that you had a bit of a mess on your hands ;)

On 08/10/2016 at 7:43 PM, Curious Pineapple said:

I'm writing an application in C# using Windows Forms.

You should consider WPF and MVVM over WinForms if at all possible. MVVM will be a natural complement to what you have described above where you are now essentially displaying generated content. Moreover you should find that you are then naturally better able to separate out your concerns in any event since this is what the pattern lend itself to.

On 08/10/2016 at 7:43 PM, Curious Pineapple said:

I have this working already between the worker thread...

In general if you are not already doing so you should be using TPL Tasks with async await. The explicit use of Threads and especially the BackgroundWorker are widely considered deprecated (or at least very niche) now.

On 08/10/2016 at 7:43 PM, Curious Pineapple said:

...it waits for the 16 bytes of serial data to arrive, then invokes a function...

You should also have a look at the BlockingCollection and consider implementing the producer consumer pattern if you haven't already done so here since this is exactly what you are describing... Your consumer task should be created with it's TaskCreationOptions parameter set to LongRunning.

On 08/10/2016 at 7:43 PM, Curious Pineapple said:

I'm thinking of having a global string that forms modify in their _load, and the serial thread uses a switch statement to invoke actions on the correct form, but that seems a rather long winded way to do things.

Indeed, don't do that. As you seem to have already realised, you should be abstracting this out to some kind of model object. Don't pollute your models with view or view model/controller logic, each layer should be kept completely agnostic/independent of the other.

 

Another implementation that can be considered when working with communications protocols, especially complicated/intricate ones is a state machine or a layered state machine. Each layer deals with a specific requirement of the protocol such as connecting, reconnecting, acking and naking, level switching and so on. Command builders and packet builders are defined separately as is the underlying communications channel and it's configuration which are all dependency injected to keep things as decoupled as possible. One's overall aim is to encapsulate the behaviour of the protocol in a series of layers that communicate state change by a clean and well defined API.

 

I'd offer more but I am recovering from an operation right now so I'm in quite a bit of pain.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×