如何在没有实例化、静态变量或传递引用的情况下从另一个类/线程访问方法

本文关键字:情况下 引用 另一个 方法 访问 线程 实例化 变量 静态 | 更新日期: 2023-09-27 18:35:49

在重新设计我的应用程序以包含更灵活的设计后,我在从线程中运行的另一个类访问位于 MAINFORM 上的方法时遇到了一些麻烦。 下面是一些代码片段,以显示我正在尝试执行的操作:

主要形式:

public void setAlarmColour(byte[] result, int buttonNumber)
    {
        if (result != null)
        {
            this.Invoke((MethodInvoker)delegate
            {
                //txtOutput1.Text = (result[4] == 0x00 ? "HIGH" : "LOW"); // runs on UI thread
                if (result[4] == 0x00)
                {
                    this.Controls["btn" + buttonNumber].BackColor = Color.Green;
                }
                else
                {
                    this.Controls["btn" + buttonNumber].BackColor = Color.Red;
                }

            });
        }

    }

A类:

public void connect(IDeviceInterface device)
    {
        //send data
        byte[] bData = new byte[71];
        bData[0] = 240;
        bData[1] = 240;
        bData[2] = 0;
        bData[3] = 1;
        bData[68] = 240;
        bData[69] = 240;
        bData[70] = this.CalculateCheckSum(bData);

        try
        {
            byte[] result = this.SendCommandResult(device.deviceIPAddress, device.devicePort, bData, 72);
            //send byte + buttonNumber to setAlarmColour on main thread here.
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

现在,回答你可能想问的几个问题,为什么我不想做标题中解释的一些事情。

  • 保存 connect() 方法的设备类在线程中运行。 这是因为我有多个这样的情况,一个用于我尝试监视的每个设备,用于 Exampl。
  • 我无法实例化一个新表单,因为我需要更新当前表单,因此 mainForm main = new mainForm() 不是一个选项
  • 主窗体中对我的方法使用 static 会导致访问它首先尝试更改的表单控件出现问题,主要是在"this.controls[]"部分。 尽管如果 anyonyone 对此有解决方法,我对想法持开放态度
  • 如果可能的话,我不想传递对主表单的引用,因为到处处理它可能会变得混乱,据我所知,这被认为是不好的做法,尤其是随着项目规模的增加。 我已经在早期版本上完成了此操作,在我到达我需要去的地方之前,我必须传递此引用大约 3/4 次。

有没有办法通过使用委托/事件等来做到这一点? 我尝试阅读有关执行此操作的信息,但其中一些似乎令人困惑,我不确定什么在哪里。另外,就像我说的,我对新想法持开放态度,所以如果你能向我展示一种以有效方式使用我排除的选项的方法,那么我就会持开放态度。

有没有人知道如何从 A 类在主窗体中访问此方法?附言如果有人需要更多信息,只需询问即可。

编辑 1:根据 Jon Skeet 的想法,我决定尝试实现事件来处理这个问题。不过我遇到了一些问题...

我的表单唯一知道该类的时间是当它根据我正在创建的类 A 的条目/实例数量动态创建它们时。在我的 A 班中,我创建了:

 public event EventHandler setAlarmColour = delegate { };

然后我在同一个类中触发事件:

 this.setAlarmColour(this, new EventArgs());

并在动态创建类期间订阅事件,如下所示:

 bfdevice.setAlarmColourDelegate += new EventHandler(setAlarmColour);

其中 bfdevice = 类 A 和 setAlarmColorDelegate 是事件处理程序,setAlarmColor 是我尝试访问的主窗体方法,但是我需要将参数传递给

 EventHandler(setAlarmColour)

即"byte[]result, int buttonNumber"因为目前我得到"设置警报颜色"没有重载匹配委托"系统.事件处理程序"有什么想法吗?

这里的问题是我需要发送到 setAlarmColor 的参数仅在类 A 中已知,这不是我订阅事件的地方。 因此我不能做 setAlarmColor(result, buttonNumber),因为 mainform 没有对这些的引用。

如何在没有实例化、静态变量或传递引用的情况下从另一个类/线程访问方法

听起来ClassA可能会暴露CommandReceived事件。然后,表单将为ClassA的每个实例订阅该事件。这实际上是在委托事件处理程序中传递对 ClassA 的引用,但它都是隐藏的。

从根本上说,ClassA的每个实例都必须以某种方式返回到表单的实例。我强烈建议您不要通过静态变量执行此操作,这会引入紧密耦合并降低可测试性。

如果你不喜欢事件的想法,你必须通过其他方式将引用传递给ClassA - 例如在构造函数中。在这种情况下,您可能会在两者之间引入一个接口 - ClassA 的构造函数将具有接口类型的参数,并且您的窗体将实现该接口。这将放松两者之间的耦合。

相关文章: