Question How to know when to Invoke?

UncleRonin

Well-known member
Joined
Feb 28, 2006
Messages
230
Location
South Africa
Programming Experience
5-10
Is it possible to execute some sort of code to determine whether or not it's a good idea to call Invoke? I dunno what you would do once you'd found out you can't but it could be useful for detecting some dead locks (like the one I have a the moment).

So can this be done? Maybe by checking the current event queue or something?? *clutches at straws*
 
Are you asking because you have a problem?

Whenever you are writing a multithreaded app, and the thread executing the code is NOT the one that created the control it wants to access, an invoke will be required. Generally, you should have mapped out in your *mind* which code is run by UI threads and which code is not, but if there is ever a situation where there genuinely could be either a UI thread or a nonUI thread calling the same bit of code, then you can ask the control if an invoke is required, using the Control.InvokeRequired Property (System.Windows.Forms)

The control remembers the thread that created it and compares the thread that is retrieving the InvokeRequired boolean, to the creating thread. If they are the same, no invoke is required.

Remember that facilities such as backgroundworker exist that handle the invocation for you.. There may be other mechanisms that are better for managing the interaction between UI and nonUI threads; if a nonUI thread has to update a label it may be better to start a timer that reads from a variable, and have the nonUI thread populate the variable. If your app is processing thousands of files a seconds, it's a waste of CPU cycles to update a label text thousands of times a second; better to just (once per second in a timer) have the UI thread retreive the last file that was processed and update the label. That way the user can see something is happening and you arent unnecessarily slowing your processing down with useless painting operations (though the impression of speed may be an intangible benefit; i normally provide a counter to say how many files have been done)
 
Yup, I most definitely have a problem! :3 It ties in with a recent post of mine.

I have a dictionary that is accessed by events triggered when a serial port receives data (main thread) and by a background thread. The dictionary stores messages to be sent out and messages are added via the main thread when data is received. The problem occurs when an incoming message is added during one data received event and another data received event attempts to remove some other message.

When a message is removed it is logged and appended to the text of an RTB via Invoke (if InvokeRequired is true).

Having a timer which processes the lists CAN work but a the same time these things are happening any number of other inputs can come through from other devices or the user and it's pretty important to make sure the logging (both to file and RTB) is sequential and displayed as it gets processed. I can live without it being in sequence but obviously I would rather try and fix this than change the behaviour.

Besides checking InvokeRequired is there no other way to determine what is currently happening with the application's events? By saying this I mean besides doing things like monitoring windows messages and deploying hooks and handles and other stuff! :3 Simplicity being the keyword here.
 
events triggered when a serial port receives data (main thread)
DataReceived event happens on secondary thread.
 
So that means that a secondary thread handles the DataReceived event. So if the main thread and the secondary thread are running simultaneously why is there a lock? Is it because The Invoke (from the secondary thread) is creating an event on the main thread at the same time the main thread is waiting for the lock to release then I take it? Ugh. That's a problem.
 
"main thread" is UI thread, the thread that runs forms, a thread you should not block. I'm not sure if you have a different meaning for "main thread" here.
 
Doing some guessing here since you haven't fully described the situation... If main thread is waiting to enter a synclock, where another thread is waiting to invoke on main thread, then you have a deadlock - two threads blocking each other. I'm sure you can rearrange things to avoid this, because the only time worker threads need to touch main thread is to update UI, and this is not part of the work cycle. As I see it you are doing something in the method that you have invoked on UI thread that calls back to the work cycle, and as I see it there is no need to do that, this can be done on the secondary thread that made the invoke call, this way UI thread will never be in a position to wait for synchronization with the worker threads and such a deadlock can't occur.
 
Actually realised that in this instance the reason for the dead lock is... wait for it... me!!

We're busy doing testing so I added code to simulate input from what would normally be a scanner input (via a SerialPort DataReceived event) by clicking a button on the GUI :3 So instead of it acting on the secondary thread like it normally would, it's coming from the main thread *cough*

So in actual fact my desired functionality is there BUT I mucked it up by going at it from the wrong direction. I didn't know that the serial port events were on a secondary thread and that's what got me. Thanks for the info about that btw. Next time I will rather check which thread is calling my functions during the dead lock so I can see!
 
Back
Top