如何在没有实例化、静态变量或传递引用的情况下从另一个类/线程访问方法
本文关键字:情况下 引用 另一个 方法 访问 线程 实例化 变量 静态 | 更新日期: 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
的构造函数将具有接口类型的参数,并且您的窗体将实现该接口。这将放松两者之间的耦合。