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

时间:2012-05-29 13:03:02

标签: c# .net events delegates instantiation

在重新设计我的应用程序之后,为了采用更灵活的设计,我遇到了一些麻烦,访问位于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;
                }


            });

        }


    }

CLASS 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()方法的设备类在一个线程中运行。这是因为我有多个这样的,一个用于我想要监控的每个设备,例如。
  • 我无法实例化新表单,因为我需要更新当前的表单,因此mainForm main = new mainForm()不是一个选项
  • 在主窗体中对我的方法使用静态会导致访问表单控件的问题,它首先尝试更改,主要是在“this.controls []”部分。虽然如果anyonyone有一个解决方法,我愿意接受想法
  • 我不想传递对主要表格IF可能的引用,因为它可能会乱七八糟地处理它,并且据我所知它被认为是不好的做法,特别是当项目规模增加时。我已经在早期版本上完成了这个,并且在我到达我需要去的地方之前,我必须通过这个参考大约3/4次。

有没有办法可以通过使用委托/事件等来做到这一点?我曾尝试阅读有关这样做但有些看起来令人困惑,我不确定会发生什么。另外,就像我说的那样,我对新想法持开放态度,所以如果你能告诉我一种使用我以有效方式排除的选项的方式,那么我就是开放的。

有没有人知道如何在A类的主窗体中访问此方法? 附:如果有人需要其他信息,只需询问。

编辑1: 来自jon双向飞碟的想法,我决定尝试并实现事件来处理这个问题。我遇到了一些问题......

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

 public event EventHandler setAlarmColour = delegate { };

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

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

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

 bfdevice.setAlarmColourDelegate += new EventHandler(setAlarmColour);

其中bfdevice = A类和setAlarmColourDelegate是事件处理程序,而setAlarmColour是我正在尝试访问的mainform中的方法, 但我需要将参数传递给

 EventHandler(setAlarmColour)

即“byte [] result,int buttonNumber” 因为目前我得到“没有重载”setAlarmColour“匹配委托”System.EventHandler“ 任何想法?

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

1 个答案:

答案 0 :(得分:3)

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

从根本上说,ClassA的每个实例都必须以某种方式返回形式的实例。我强烈建议你通过静态变量来做这件事,这会引入紧密耦合并降低可测试性。

如果您不喜欢该活动创意,则必须以其他方式将引用传递给ClassA - 例如在构造函数中。在这种情况下,您可能会在两者之间引入一个接口 - ClassA的构造函数将具有接口类型的参数,并且您的表单将实现该接口。这会放松两者之间的耦合。