none
thread 傳址的方法? RRS feed

  • 問題

  • 是這樣的,小弟有一支class,現在小弟在form1內將這支class的某一method 用thread的方式來run

    小弟希望這個thread可以更改Form1上的RichTextBox的內容, 所以想盡辦法想把Form1的位置傳入…

    但苦思不出其解,實在很苦惱…以前寫在Form內的Function很容易就可以利用Delegate的方式來變更Main Thread中控制項的值,
    但Function寫到Class內後就想不到辦法了,還請有經驗的前輩能給小弟一些指導,謝謝。
    2009年5月7日 下午 02:46

解答

所有回覆

  • EdwardEric:
         你的問題是類似以下這個討論嗎?
         http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/cb712d13-dbd5-4667-81df-fd1ce00ac98e
    • 已標示為解答 EdwardEric 2009年5月10日 下午 04:30
    2009年5月7日 下午 06:12
    版主
  • 是的,頗類似這樣的情況 code大概如下,ListenClient是一支監聽Client請求的Class,初始會傳入一個Socket的物件給它
          

                Sk = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    
                Sk.Bind(IEP)
    
                Sk.Listen(20)
    
                Me.ShowS.Text = "Server Started in :" + IEP.Address.ToString() + " Port:" + ServerPort
    
                Dim lc As New ListenClient(Sk)
                Dim ServerThread As New Thread(New ThreadStart(AddressOf lc.ServerThreadProc))
        
                ServerThread.Start()
    而原本ListenClient的method我是寫在Form 裡面,然後用以下code來達成委派

    Private Delegate Sub UpdateUICallBack(ByVal newText As String, ByVal txt As Control)
    
        Private Sub UpdateUI(ByVal newText As String, ByVal c As Control)
            If Me.InvokeRequired() Then
                Dim cb As New UpdateUICallBack(AddressOf UpdateUI)
                Me.Invoke(cb, newText, txt)
            Else
                txt.Text = newText
            End If
        End Sub
    

    method裡則直接呼叫UpdateUI("message",Me.RichTextBox)

    換到Class裡的話,就沒辦法呼叫到UpdateUI了…


    不好意思,由於委派的方式google了很久還是沒辦法很了解,現有的書上也都沒寫的很清楚-_-
    先謝過二位前輩的回覆。
    2009年5月8日 上午 01:23
  • Code怎摸怪怪的
       Private Sub UpdateUI(ByVal newText As String, ByVal c As Control)
            If Me.InvokeRequired() Then
                Dim cb As New UpdateUICallBack(AddressOf UpdateUI)
                Me.Invoke(cb, newText, txt)
            Else
                txt.Text = newText
            End If
        End Sub
    UpdateUI看不到txt
    UpdateUICallBack委派才看的到txt

    要放到Class內,沒測試不是很確定,不過應該可以改成透過控制項去檢查InvokeRequired
        Private Sub UpdateUI(ByVal newText As String, ByVal c As Control)
            If c.InvokeRequired() Then
    Dim cb As New UpdateUICallBack(AddressOf UpdateUI) c.Invoke(cb, newText, c )
    Else c.Text = newText
    End If End Sub
    因為控制項也在主執行緒

    http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 EdwardEric 2009年5月10日 下午 04:30
    2009年5月8日 上午 01:39
  • ok…我參考了各位給的資料,加上一些改變,終於可以run了,不過改好後出現了一個很奇怪的問題,Client 斷線後,MainThread竟然會多開一個Form @@" 連一次就開一個…
    p.s 後來發現是我先前為了測試bill前輩在另一討論串解答的一個現象而 keyin的Form.show忘了拿掉… 2009/5/11
    更改後的重點code如下

    class內
     Private serverSocket As System.Net.Sockets.Socket
    
        Delegate Sub UpdateUICallBack(ByVal newText As String)
    
        Delegate Sub STP()
    
        Private CallBackMethod As UpdateUICallBack
    
        Private m_RunThread As STP
    
        Private RunThread As Thread
    
        Private m_c As Control
    
    
    
        Public Sub Start()
    
            RunThread.Start()
    
        End Sub
    
    
    
        Private Sub ThreadFunction()
    
            m_RunThread.Invoke()
    
        End Sub
    
        Public Sub UpdateUI(ByVal msg As String)
    
            If m_c IsNot Nothing AndAlso CallBackMethod IsNot Nothing Then
    
                m_c.Invoke(CallBackMethod, New Object() {msg})
    
            End If
    
        End Sub
    
    
    
        Public Sub New(ByVal serverSocket As System.Net.Sockets.Socket, ByRef m_callback As UpdateUICallBack, ByRef c As Control)
    
            Me.serverSocket = serverSocket
    
            m_c = c
    
            CallBackMethod = m_callback
    
            m_RunThread = AddressOf ServerThreadProc
    
            RunThread = New Thread(AddressOf ThreadFunction)
    
            Form1.Label2.Text = "Listening...."
    
        End Sub
    
    
    
    Sub ServerThreadProc()
    
    '實際要使用的method,會呼叫UdateUI來傳送訊息
    form內的
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
    Dim lc As New ListenClient(Sk, AddressOf CallBackMethod, Me) lc.Start() End Sub Sub CallBackMethod(ByVal message As String) Me.StausRTB1.AppendText(message & vbLf) End Sub
    感謝各位的回答^^" 其實小弟是最近才開始有在做比較深入的thread的程式,來這裡發問實在是受益良多
    • 已編輯 EdwardEric 2009年5月10日 下午 04:32 問題已解
    2009年5月8日 上午 02:32