Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的事件在未分配给任何控件/从未分配给特定控件时触发?_C# - Fatal编程技术网

C# 为什么我的事件在未分配给任何控件/从未分配给特定控件时触发?

C# 为什么我的事件在未分配给任何控件/从未分配给特定控件时触发?,c#,C#,所以我有一段代码刷新窗体上的控件,以反映连接设备中的寄存器状态。在这段代码中,我使用MethodInvoker将该过程执行到另一个线程中,这样就不会锁定整个UI,类似于异步刷新。无论如何,在这个MethodInvoker主体中,我首先“-=newEventHandler(this.\u assignedEvent)”,禁用该控件,根据设备寄存器状态更新它的一个属性,然后重新启用该控件,并重新分配EventHandler 在我当前的项目中,我已经重复了好几次,大约90%的时间,这是有效的。但是,对

所以我有一段代码刷新窗体上的控件,以反映连接设备中的寄存器状态。在这段代码中,我使用MethodInvoker将该过程执行到另一个线程中,这样就不会锁定整个UI,类似于异步刷新。无论如何,在这个MethodInvoker主体中,我首先“-=newEventHandler(this.\u assignedEvent)”,禁用该控件,根据设备寄存器状态更新它的一个属性,然后重新启用该控件,并重新分配EventHandler

在我当前的项目中,我已经重复了好几次,大约90%的时间,这是有效的。但是,对于我在特定表单上拥有的大约三/四个控件,会发生以下情况:

  • 删除控件x的事件
  • 修改控件x
  • 控件y的事件已激发,事件从未分配给x,从未
  • 触发控件x的事件
  • 我感到困惑
  • 这只发生在少数几个select控件上,我想知道是否有一些我不遵守的跨线程执行规则或者其他什么

    有关的刷新代码如下所示:

    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
    }