none
請問怎麼解決使用"委派"時出現的「參考非共用成員需要物件參考」的錯誤呢? RRS feed

  • 問題

  • 下面程式是自己想要練習執行緒及委派的練習,在呼叫委派時出現「參考非共用成員需要物件參考」,
    該怎麼樣才可以完成跨執行緒的 UI 更新呢?

       

        Class ThreadWork
            Friend Sub RunSample01()
                For i = 1 To 10000
                    i += i
                    myUI("i", TextBox1)       '<---參考非共用成員需要物件參考。 
                Next
            End Sub
        End Class
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            Dim run As New ThreadWork
            Dim myRun As New ThreadStart(AddressOf run.RunSample01)
            For i As Integer = 0 To 5
                Try
    
                    Dim myThread As New Thread(myRun)
                    myThread.Start()
    
                Catch generatedExceptionName As Exception
    
                    Exit Try
    
                End Try
            Next
        End Sub
    
        Private Delegate Sub myUICallBack(ByVal myStr As String, ByVal ctl As Control)
        Private Sub myUI(ByVal myStr As String, ByVal ctl As Control)
            If Me.InvokeRequired Then
                Dim myUpdate As New myUICallBack(AddressOf myUI)
                Me.Invoke(myUpdate, myStr, ctl)
            Else
                ctl.Text = myStr
            End If
        End Sub


    • 已編輯 C.Kevin 2012年3月14日 上午 02:48
    2012年3月14日 上午 02:40

解答

  • 你需要做下列去更正這個錯誤:

    1. 將執行個體宣告為物件變數。
    2. 使用變數名稱參考執行個體。

    你可以看一下這個做參考,
    如何建立及使用共用成員使用 Visual Basic.NET 或 Visual Basic 2005


    大家一齊探討、學習和研究,謝謝!
    Microsoft MVP, Microsoft Community Star(TW & HK), MCT,
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD
    MVP for VB.NET since 2003

    2012年3月14日 上午 02:48
    • 已提議為解答 Alex_Lee 2012年3月14日 上午 03:23
    • 已標示為解答 璉璉Moderator 2012年3月24日 上午 03:48
    2012年3月14日 上午 03:13
  • 在 MSDN 文件庫 [Visual Basic 中的物件和類別]提到以下:

    執行個體成員和共用成員

    當您從類別建立物件時,即是建立該類別的執行個體。 未使用 Shared (Visual Basic) 關鍵字宣告的成員是「執行個體成員」(Instance Member),必定是屬於該特定執行個體。 執行個體中的執行個體成員,不會受到同一類別的其他執行個體中相同成員的影響。 例如,執行個體成員變數在不同的執行個體中可有不同的值。

    使用 Shared關鍵字宣告的成員是「共用成員」(Shared Member),這些成員屬於整個類別而不屬於任何特定的執行個體。 無論類別建立了多少執行個體,或甚至沒有建立執行個體,共用成員只能存在一次。 例如,共用成員變數只有一個值,而可存取該類別的所有程式碼都可使用此值。

    -----------------------------------

    (1) 你的 MyUI 方法是宣告在某個 Form Class 內, 沒有用 Shared 關鍵字宣告, 所以它是執行個體成員.

    (2) 執行個體成員的意義在於它必須在執行個體內存活.

    (3) 所以解決方法是

    (3-1) 要不就把 Form1 類別執行個體傳遞給 ThreadWork類別執行個體

    (3-2) 要不就使用 Shared 關鍵字把 MyUI 宣告為靜態方法 (也就是變成類別的共用成員之意)

    補充: 記得把上面的 link 內容連進去看一遍, 把觀念弄清楚.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2012年3月14日 上午 05:50
    版主

所有回覆

  • 你需要做下列去更正這個錯誤:

    1. 將執行個體宣告為物件變數。
    2. 使用變數名稱參考執行個體。

    你可以看一下這個做參考,
    如何建立及使用共用成員使用 Visual Basic.NET 或 Visual Basic 2005


    大家一齊探討、學習和研究,謝謝!
    Microsoft MVP, Microsoft Community Star(TW & HK), MCT,
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD
    MVP for VB.NET since 2003

    2012年3月14日 上午 02:48
    • 已提議為解答 Alex_Lee 2012年3月14日 上午 03:23
    • 已標示為解答 璉璉Moderator 2012年3月24日 上午 03:48
    2012年3月14日 上午 03:13
  • 謝謝 2 位大大的回覆,KenLin 大大附的參考資料看得懂,不知道怎麼利用,
    阿尼大大附的參考資料對我來說還太難了,看不董...

    2012年3月14日 上午 05:13
  • 在 MSDN 文件庫 [Visual Basic 中的物件和類別]提到以下:

    執行個體成員和共用成員

    當您從類別建立物件時,即是建立該類別的執行個體。 未使用 Shared (Visual Basic) 關鍵字宣告的成員是「執行個體成員」(Instance Member),必定是屬於該特定執行個體。 執行個體中的執行個體成員,不會受到同一類別的其他執行個體中相同成員的影響。 例如,執行個體成員變數在不同的執行個體中可有不同的值。

    使用 Shared關鍵字宣告的成員是「共用成員」(Shared Member),這些成員屬於整個類別而不屬於任何特定的執行個體。 無論類別建立了多少執行個體,或甚至沒有建立執行個體,共用成員只能存在一次。 例如,共用成員變數只有一個值,而可存取該類別的所有程式碼都可使用此值。

    -----------------------------------

    (1) 你的 MyUI 方法是宣告在某個 Form Class 內, 沒有用 Shared 關鍵字宣告, 所以它是執行個體成員.

    (2) 執行個體成員的意義在於它必須在執行個體內存活.

    (3) 所以解決方法是

    (3-1) 要不就把 Form1 類別執行個體傳遞給 ThreadWork類別執行個體

    (3-2) 要不就使用 Shared 關鍵字把 MyUI 宣告為靜態方法 (也就是變成類別的共用成員之意)

    補充: 記得把上面的 link 內容連進去看一遍, 把觀念弄清楚.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2012年3月14日 上午 05:50
    版主
  • 抱歉,昨天不在,我看了「Visual Basic 中的物件和類別」,裡面是不是在講 "物件導向" 的概念? 以及建立新物件(關鍵字 New)的方式呢?



    請問解決方法 (3-1) 我的打法是;

    Class ThreadWork
            Friend Sub RunSample01()
                Dim f As Form1
                For i = 1 To 100
                    'i = i
                    f.myUI("i", TextBox1)      '<---還是有出現 "參考非共用成員需要物件參考。"
                Next

            End Sub
        End Class

    ---------------------------------------------------------------------------------------------------------

        Private Delegate Sub myUICallBack(ByVal myStr As String, ByVal ctl As Control)
        Public Shared Sub myUI(ByVal myStr As String, ByVal ctl As Control)      '<--- Shared 加在這出現了 "沒有類別的明確執行個體,因此無法從共用方法或共用成員初始設定式中參考至類別的執行個體成員。"錯誤訊息。


            If InvokeRequired Then
                Dim myUpdate As New myUICallBack(AddressOf myUI)
                Invoke(myUpdate, myStr, ctl)
            Else
                ctl.Text = myStr
            End If
            End Sub

    如果另建一個新類別把委派跟 myUI 放進去話換 InvokeRequired 跟 Invoke 變成 "參考非共用成員需要物件參考。"




    • 已編輯 C.Kevin 2012年3月16日 上午 03:02
    2012年3月16日 上午 12:34
  • 不使用 Shared的方式.

       Class ThreadWork
            Public Property MyParent as Form
            Friend Sub RunSample01()
                For i = 1 To 10000
                    i += i
                    MyParent.myUI("i", TextBox1)        
                Next
            End Sub
        End Class


     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim run As New ThreadWork
            Dim myRun As New ThreadStart(AddressOf run.RunSample01)
            For i As Integer = 0 To 5
                Try

                    Dim myThread As New Thread(myRun)
                    myThread.MyParent=Me
                    myThread.Start()

                Catch generatedExceptionName As Exception

                    Exit Try

                End Try
            Next
        End Sub


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年3月16日 上午 06:45
    版主
  • 請問 TextBox 在委派那段程式碼用 Control 類別去控制元件,這時如果想改成 ProgressBar 顯示該用什麼類別去控制呢?
    查 MSDN 看不出所以然...

    我打了後有出現了一些錯誤訊息。
    下面是整個程式的完整碼。

    Imports System.Threading

    Public Class Form1

        Class ThreadWork
            Public Property MyParent() As Form      '<---沒有 'ReadOnly' 或 'WriteOnly' 規範的 Property 必須提供 'Get' 和 'Set'。
             Friend Sub RunSample01()      '<---陳述式不可以在屬性主體中出現。已假設是屬性結尾。
                 For i = 1 To 100
                    MyParent.myUI("i", TextBox1)
                Next
            End Sub
        End Class

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim run As New ThreadWork
            Dim myRun As New ThreadStart(AddressOf run.RunSample01)
            For i As Integer = 0 To 5
                Try
                    Dim myThread As New Thread(myRun)
                    myThread.MyParent = Me        '<---'MyParent' 不是 'System.Threading.Thread' 的成員。

                    myThread.Start()
                Catch generatedExceptionName As Exception
                    Exit Try
                End Try
            Next
        End Sub

        Private Delegate Sub myUICallBack(ByVal myStr As String, ByVal ctl As Control)
        Private Sub myUI(ByVal myStr As String, ByVal ctl As Control)
            If Me.InvokeRequired Then
                Dim myUpdate As New myUICallBack(AddressOf myUI)
                me.Invoke(myUpdate, myStr, ctl)
            Else
                ctl.Text = myStr
            End If
        End Sub
    End Class

    • 已編輯 C.Kevin 2012年3月16日 上午 08:40
    2012年3月16日 上午 08:38
  • 沒有 'ReadOnly' 或 'WriteOnly' 規範的 Property 必須提供 'Get' 和 'Set'。

    以上的問題是因為你不是用 2010 .

    所以請改成

    Private _myParentForm as Form

    Public Property MyParent() As Form

    Get

      Return _myParentForm

    End Get

    Set (Byval value as Form)

       _myParentForm=value

    End Set

    把 [逐步解說:定義類別 (Visual Basic)] 看一看, 搞清楚類別中可以定義什麼東西, 怎麼定義, 如果你看不懂, 表示你現階段寫的東西和程度不符, 先找點簡單的題目做.

    學寫程式一個很重要的事情, 當你看到一個明確的錯誤訊息, 先找看看有沒有相關的東西可以看, 至少可以複製錯誤訊息到搜尋引擎上查一下吧 ? (我剛剛查的結果)  不是直接伸手. 如果你永遠是直接別人貼一行, 你複製一行, 那你永遠學不會.

    如果有可能, 去買本入門的書按步就班學, 因為我看你貼的程式碼已經完全亂了步調.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年3月16日 上午 08:52
    版主
  • 我暫時放棄好了,改完還是會出現「MyParent' 不是 'System.Threading.Thread' 的成員。」的錯誤訊息。
     [逐步解說:定義類別 (Visual Basic)] 的範例,有去用逐步執行弄懂彼此關係,

    Class 中;
    Sub New -- 指定初值
    Get -- 讀取時將值丟出來時用(讀取屬性)
    Set -- 設定屬性
    Public Sub Capitalize --撰寫函數工作內容

    Form 中;
    New -- 宣告新物件
    user.Capitalize() -- 使用方法,跟呼叫副程式的感覺有點像
    不過 「user As New UserNameInfo("Moore, Bobby")」跟「user.UserName = "Worden, Joe"」不懂為什麼給值的方式不一樣,

    這些是目前了解的深度,有不對的地方還請指教,瞭解了還是不懂怎麼改,暫時放棄了,謝謝 Bill 大大。
    的確亂了步調,不知道怎麼改就亂試一通。


    2012年3月17日 上午 01:52
  • 你可以先依照幾個步驟去搞懂類別

    (1) 你要先知道類別是做什麼用的 ? 執行個體是什麼 ? 類別和執行個體(物件) 有什麼不同  ? 物件變數和物件 (執行個體) 又有什麼不同.

    (2) 類別裡面可以寫些什麼 ?

    (2-1) 練習寫方法 (Method), 這應該比較簡單, 但你可以試著寫執行個體方法(也就是沒有 Shared 宣告的), 與共用方法(靜態方法 也就是用 Shared 宣告的), 然後用這個類別去產生一個執行個體, 分清楚有沒有加 Shared 在呼叫上會有什麼差別 ?

    (2-2) 練習寫 Property (屬性), 花點時間弄懂屬性和欄位有什麼不同, 在屬性中的 Get 與 Set 又是做什麼的.

    (2-3) 再來你就可以練習寫 Event (事件).

    這些在MSDN 文件庫都有, 索引你也有了, 所以先瞭解這些東西, 再把你的這個程式繼續下去會好一點.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年3月17日 上午 03:25
    版主