簡體   English   中英

如何在沒有實例化,靜態變量或傳遞引用的情況下從另一個類/線程訪問方法?

[英]how do you access a method from another class / thread without instantiation, static variables or passing references?

在重新設計了應用程序以結合更靈活的設計之后,我遇到了從另一個在線程中運行的類訪問位於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()方法的設備類在線程中運行。 這是因為我要進行多個操作,例如我要監視的每個設備一個。
  • 我無法實例化新表單,因為我需要更新當前表單,因此mainForm main = new mainForm()是不可選項
  • 在主要形式的方法上使用static會導致訪問首先要更改的形式控件的問題,主要是在“ this.controls []”部分。 盡管任何人都有解決方法,但我很樂意
  • 我不想傳遞對主要形式的引用(如果可能的話),因為它可能會在各處出現混亂,並且據我所知這被認為是不好的做法,尤其是隨着項目規模的擴大。 我已經在較早的版本上執行了此操作,並且在到達所需位置之前,我必須通過此引用約3/4次。

有沒有辦法我可以通過使用委托/事件等來做到這一點? 我已經嘗試閱讀有關執行此操作的信息,但其中有些似乎令人困惑,而且我不確定該怎么辦。 另外,就像我說的那樣,我樂於接受新想法,因此,如果您可以向我展示一種有效使用我排除的選項的方法,那么我會開放的態度。

有誰知道如何在A類的主要表單中訪問此方法? ps如果有人需要其他信息,只需詢問。

編輯1:根據喬恩·斯凱特(Jon skeet)的想法,我決定嘗試實施一些事件來處理此問題。 我遇到了一些問題...

我的表單唯一了解該類的時間是它根據我正在創建的A類的條目數/實例動態創建它們的時間。 在我的A類中,我創建了:

 public event EventHandler setAlarmColour = delegate { };

然后我在相同的類中觸發該事件:

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

並在動態創建類的過程中訂閱事件,例如:

 bfdevice.setAlarmColourDelegate += new EventHandler(setAlarmColour);

其中bfdevice = A類,setAlarmColourDelegate是事件處理程序,setAlarmColour是我嘗試訪問的主窗體中的方法,但我需要將參數傳遞給

 EventHandler(setAlarmColour)

即“ byte [] result,int buttonNumber”,因為目前我正在獲取“ setAlarmColour沒有重載”匹配委托“ System.EventHandler”的任何想法?

這里的問題是,我需要發送給setAlarmColour的參數僅在類A中是已知的,這不是我要訂閱該事件的地方。 所以我不能做setAlarmColour(result,buttonNumber)因為主窗體沒有對這些的引用。

聽起來ClassA可以公開CommandReceived事件。 然后,該表單將為ClassA每個實例訂閱該事件。 實際上是在委托事件處理程序中傳遞對ClassA的引用,但都被隱藏了。

從根本上講, ClassA每個實例都必須以某種方式返回到表單的實例。 我強烈建議您不要通過靜態變量來執行此操作,因為這會導致緊密耦合並降低可測試性。

如果您不喜歡事件的主意,則必須以其他方式將引用傳遞給ClassA ,例如在構造函數中。 在這種情況下,您可能會在兩者之間引入一個接口ClassA的構造函數將具有接口類型的參數,而您的表單將實現該接口。 這將放松兩者之間的耦合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM