Controller events and threads
Overview
A controller event is a message from the controller that something has happened. Events can be caught and acted upon by PC SDK applications.
Controller events use their own threads. This means that user interface threads and controller event threads can get into conflict. This section gives information on how to prevent this.
Controller events
PC SDK applications can subscribe to a number of controller events. These are all described in the Reference Manual PC SDK.
The following table shows some events that exists in the PC SDK.
The event... | occurs when... |
---|---|
StateChanged | the controller state has changed. |
OperatingModeChanged | the controller operating mode has changed. |
ExecutionStatusChanged | the controller execution status has changed. |
Changed | the value or the state of the I/O signal has changed. |
MessageWritten | the EventLog has a new message |
ValueChanged | the value of a RAPID data has changed. |
Note
There is no guarantee you will get an initial event when setting up/activating a controller event. You need to read the initial state from the controller.
GUI and controller event threads in conflict
You should be aware that controller events use their own threads on the PC platform. If a GUI thread and a controller event thread get into conflict, deadlocks or overwritten data may occur. This may happen when a controller event is succeeded by an update of the user interface, which is indeed a very common scenario.
You then need to take action in your code to control that the user interface update is executed by the GUI thread and not by the
controller event thread. This is done by enforcing a thread switch using the Invoke
or BeginInvoke
method. For more information
with code examples, see Invoke method.
On the other hand, if the controller event should NOT cause any update of the user interface, you should not take any special action.
Using Invoke
/ BeginInvoke
is performance demanding and should not be used more than necessary.
Note
Thread conflicts often cause hangings. The PC application UI then stops responding and the application has to be restarted.
Examine what exception has been thrown when you encounter such a situation. The exception System.InvalidOperationException
(PC platform) indicate thread conflicts. See the next section for information on how to use Invoke
to solve the problem.
Invoke method
All PC application windows views must inherit Control
/ TpsControl
, which implement Invoke
and BeginInvoke
. These methods
execute the specified delegate/event handler on the thread that owns the control's underlying window handle, thus enforcing a switch
from a worker thread to the GUI thread. This is precisely what is needed when a controller event needs to be communicated to the
end user of the system.
Invoke
should be called inside the event handler taking care of the controller event. Notice that you have to create a new
object array for the sender and argument objects:
this.Invoke(new EventHandler(UpdateUI), new Object[] { this, e });
Also notice that if you use EventHandler
in the Invoke
method and not the specific delegate class, for example
DataValueChangedEventHandler
, you need to typecast the argument in the delegate which updates the user interface. How this is done
is shown by the example below:
private void UpdateUI(object sender, EventArgs e)
{
StateChangedEventArgs args;
args = (StateChangedEventArgs)e;
this.label1.Text = args.NewState.ToString();
}
The difference between Invoke
and BeginInvoke
is that the former makes a
synchronous call and will hang until the GUI operation is completed, whereas
BeginInvoke
executes the specified event handler asynchronously. Which
method you want to use depends on the logics of your program. The
recommendation is to choose BeginInvoke
whenever possible.
If your code tries to access a GUI control from a background thread, the .NET
common language runtime will throw a System.NotSupportedException
(FlexPendant platform) or a System.InvalidOperationException
(PC platform).