C# 为什么我的事件在未分配给任何控件/从未分配给特定控件时触发?
所以我有一段代码刷新窗体上的控件,以反映连接设备中的寄存器状态。在这段代码中,我使用MethodInvoker将该过程执行到另一个线程中,这样就不会锁定整个UI,类似于异步刷新。无论如何,在这个MethodInvoker主体中,我首先“-=newEventHandler(this.\u assignedEvent)”,禁用该控件,根据设备寄存器状态更新它的一个属性,然后重新启用该控件,并重新分配EventHandler 在我当前的项目中,我已经重复了好几次,大约90%的时间,这是有效的。但是,对于我在特定表单上拥有的大约三/四个控件,会发生以下情况:C# 为什么我的事件在未分配给任何控件/从未分配给特定控件时触发?,c#,C#,所以我有一段代码刷新窗体上的控件,以反映连接设备中的寄存器状态。在这段代码中,我使用MethodInvoker将该过程执行到另一个线程中,这样就不会锁定整个UI,类似于异步刷新。无论如何,在这个MethodInvoker主体中,我首先“-=newEventHandler(this.\u assignedEvent)”,禁用该控件,根据设备寄存器状态更新它的一个属性,然后重新启用该控件,并重新分配EventHandler 在我当前的项目中,我已经重复了好几次,大约90%的时间,这是有效的。但是,对
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);
}
));
}
我建议您阅读本文和本文,检查您是否正确使用methodinvoker 如果您解释第一个代码块被触发运行的时间和人员,建议您一个替代解决方案也可能会有所帮助 评论后编辑 很抱歉,因为没有所有的源代码,所以很难提出任何建议。它看起来像是一个事件订阅者遗留在代码中的某个地方,或者与事件和多线程环境相关的问题,如 另一个建议可能是另一种解决方案,例如使用标志,而不是控制具有某些副作用的事件订阅。您可以创建一个线程安全属性,该属性指示不应由SelectedIndexChanged过程处理的更新进度
UpdateControlUsingMethod(new MethodInvoker(
() =>
{
//this._prbsRxLockTime.SelectedIndexChanged -= new System.EventHandler(this._prbsRxLock_SelectedIndexChanged);
this._prbRxLockTimeUpdatingByThread = true;
//the code has been omitted here
//this._prbsRxLockTime.SelectedIndexChanged += new System.EventHandler(this._prbsRxLock_SelectedIndexChanged);
this._prbRxLockTimeUpdatingByThread = false;
}
));
然后,您可以在事件处理程序中检查该属性是否未运行标准过程
private void _prbsRxLOL_SelectedIndexChanged(object sender, EventArgs e)
{
if (this._prbRxLockTimeUpdatingByThread)
return;
//the code has been omitted here
}
希望有此帮助。第一个代码块由主线程触发,它运行一个门户应用程序,将包含此代码的UI作为程序集加载。它由事件(刷新按钮、OneNet等)触发。第一个代码块是几个非常相似的代码块之一,这些代码块都包含在大型刷新方法中。例如,代码中接下来的几行看起来与第一个块完全相同,只是寄存器地址、位掩码和控件名称发生了更改。James,这可能很简单,比如在订阅其他代码块上的事件时,写入prbsRxLOL_SelectedIndexChanged而不是prbsRxLock_SelectedIndexChanged之类的方法名称输入错误。建议您搜索“prbsRxLOL\u SelectedIndexChanged”和“.SelectedIndexChanged+=new System.EventHandler”(“用于不正确使用的关键字。我首先考虑了这一点并检查了事件的误用情况,但找不到任何不应该存在的引用。
private void _prbsRxLOL_SelectedIndexChanged(object sender, EventArgs e)
{
if (this._prbRxLockTimeUpdatingByThread)
return;
//the code has been omitted here
}