So I have this bit of code that refreshes controls on a form to reflect register states in a connected device. In this code, I use MethodInvoker to perform the process into another thread such as to not lock up the entire UI, kind of an asynchronous refresh. Anyways, in this MethodInvoker body, I first "-= new EventHandler(this._assignedEvent)", disable the control, update one of it's properties based on the device register status, and re-enable the control, and reassign the EventHandler.
I have replicated this several times throughout my current project, and about 90% of the time, this works. However for a about three/four controls I have on a particular form this is what happens:
- Remove event for control x
- Modify control x
- Event for control y is fired, event was never assigned to x, ever.
- Event for control x is fired
- me = confused
And this only happens to a few select controls and I was wondering if there was some cross thread execution rules that I didn't adhere to or something...
The refresh code in question looks something like below:
if (_prbsRxLockTime.Enabled)
{
ParentDevice.Dongle.Read((RxSelect() == 0 ? _registers.PRBS_RX_2 : _registers.PRBS_RX_16).Offset.ToString("X"), ref result, 1);
bitMask = (ushort)(Bit.B0 | Bit.B1 | Bit.B2 | Bit.B3);
UpdateControlUsingMethod(new MethodInvoker(
() =>
{
this._prbsRxLockTime.SelectedIndexChanged -= new System.EventHandler(this._prbsRxLock_SelectedIndexChanged);
this._prbsRxLockTime.Enabled = false;
foreach (object i in _prbsRxLockTime.Items)
{
KeyValuePair<string, ushort> item = (KeyValuePair<string, ushort>)i;
if ((ushort.Parse(result, NumberStyles.HexNumber) & bitMask) == (ushort)(item.Value))
{
_prbsRxLockTime.SelectedItem = i;
break;
}
}
this._prbsRxLockTime.Enabled = true;
this._prbsRxLockTime.SelectedIndexChanged += new System.EventHandler(this._prbsRxLock_SelectedIndexChanged);
}
));
}
The event that is fired upon modifying _prbsRxLockTime.SelectedItem is this:
private void _prbsRxLOL_SelectedIndexChanged(object sender, EventArgs e)
{
ushort comboBoxData = (ushort)(((ComboBox)sender).SelectedValue);
ushort bitMask = (ushort)(Bit.B0 | Bit.B1 | Bit.B2 | Bit.B3);
string regAddress = string.Empty;
string regData = comboBoxData.ToString("X").PadLeft(4, '0');
switch (((ComboBox)sender).Name)
{
case "_prbsRxLOLTime":
regAddress = (RxSelect() == 0 ? _registers.PRBS_RX_5 : _registers.PRBS_RX_19).Offset.ToString("X");
break;
case "_prbsRxLOLThresh":
regAddress = (RxSelect() == 0 ? _registers.PRBS_RX_6 : _registers.PRBS_RX_20).Offset.ToString("X");
break;
default:
break;
}
ParentDevice.Dongle.Modify(regAddress, regData, 1, bitMask);
}1.4.