none
請問 VB2005 中 Handles 怎會是執行緒? RRS feed

  • 問題

  •  'SerialPort Data Receive Append Safe Thread
        Private Sub AppendSafeThread()
            Dim Rcount As Integer
            Dim Buffer() As Byte
            Rcount = SerialPort1.BytesToRead
            ReDim Buffer(Rcount - 1)
            SerialPort1.Read(Buffer, 0, Rcount)
            AppendReceive(Buffer)
        End Sub
        'Change Receiver Mode Universal to Binary Mode
        Private Sub ChangeRVMode()
            If rbReceive_V.Checked Then
                rbReceive_B.Checked = True 這一行說是不同執行緒, 那是怎麼回事?
                OldMode_R = 1
            End If
        End Sub
        'SerialPort Data Received must Call Receive Thread make safely Receive
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            ChangeRVMode()
            Me.AppendThread = New Thread(New ThreadStart(AddressOf Me.AppendSafeThread))
            Me.AppendThread.Start()
        End Sub
    2019年12月10日 上午 07:26

解答

  • rbReceive_B 是在 UI 執行緒(主執行緒)的控制項,
    DataReceived 是在被引發在次執行緒的事件,
    在 次執行緒 DataReceived、ChangeRVMode 更改主執行緒的控制項會引發錯誤.

    請參考:
    SerialPort.DataReceived 事件 (System.IO.Ports) | Microsoft Docs
    https://docs.microsoft.com/zh-tw/dotnet/api/system.io.ports.serialport.datareceived

    其中有一段中譯:
    從物件接收資料時, DataReceived會在次要執行緒上引發事件。 SerialPort 因為這個事件是在次要執行緒上引發,而不是主執行緒,所以嘗試修改主執行緒中的某些專案(例如 UI 元素)可能會引發執行緒例外狀況。 如果需要修改主要Form或Control中的專案,請使用Invoke將變更要求回傳,這會在適當的執行緒上執行工作。

    另建議參考:
    Serial Port 系列(8) 基本篇 -- 使用DataReceived 事件接收資料 | .Net 海角點部落 - 點部落
    https://dotblogs.com.tw/billchung/2012/01/20/66860


    Ader

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:28
    2019年12月10日 下午 12:17
  •  'SerialPort Data Receive Append Safe Thread
        Private Sub AppendSafeThread()
            Dim Rcount As Integer
            Dim Buffer() As Byte
            Rcount = SerialPort1.BytesToRead
            ReDim Buffer(Rcount - 1)
            SerialPort1.Read(Buffer, 0, Rcount)
            AppendReceive(Buffer)
        End Sub
        'Change Receiver Mode Universal to Binary Mode
        Private Sub ChangeRVMode()
            If rbReceive_V.Checked Then
                rbReceive_B.Checked = True 這一行說是不同執行緒, 那是怎麼回事?
                OldMode_R = 1
            End If
        End Sub
        'SerialPort Data Received must Call Receive Thread make safely Receive
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            ChangeRVMode()
            Me.AppendThread = New Thread(New ThreadStart(AddressOf Me.AppendSafeThread))
            Me.AppendThread.Start()
        End Sub

    TechNet 論壇主要討論企業 IT 相關產品及技術,
    如有程式開發相關問題請移駕至 MSDN 論壇

    本文已協助移動


    蘇老碎碎念
    資訊無涯,回頭已不見岸
    Facebook - 微軟台灣官方論壇愛好者俱樂部

    論壇不是神壇,沒人會通靈知道問題狀況
    請正確簡述標題及詳述狀況
    如何在論壇正確發問,可以參考iThome的文章:
    如何問到我要的答案

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:27
    2019年12月10日 下午 02:16
    版主
  • 通常,Main Thread 就是 GDI Thread ,其他都是 Work Thread 。

    WindowMessage -> GDI Thread -> DataReceived (Work Thread A) -> ChangeRVMode/ Thread.Start (A) -> AppendSafeThread (Work Thread B)

    如果你的rbReveive_B是控制項的屬性,則只能被GDI Thread 變更,則你在Thread A 要委派給GDI Thread 進行屬性變更。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:27
    2019年12月10日 下午 03:24

所有回覆

  • rbReceive_B 是在 UI 執行緒(主執行緒)的控制項,
    DataReceived 是在被引發在次執行緒的事件,
    在 次執行緒 DataReceived、ChangeRVMode 更改主執行緒的控制項會引發錯誤.

    請參考:
    SerialPort.DataReceived 事件 (System.IO.Ports) | Microsoft Docs
    https://docs.microsoft.com/zh-tw/dotnet/api/system.io.ports.serialport.datareceived

    其中有一段中譯:
    從物件接收資料時, DataReceived會在次要執行緒上引發事件。 SerialPort 因為這個事件是在次要執行緒上引發,而不是主執行緒,所以嘗試修改主執行緒中的某些專案(例如 UI 元素)可能會引發執行緒例外狀況。 如果需要修改主要Form或Control中的專案,請使用Invoke將變更要求回傳,這會在適當的執行緒上執行工作。

    另建議參考:
    Serial Port 系列(8) 基本篇 -- 使用DataReceived 事件接收資料 | .Net 海角點部落 - 點部落
    https://dotblogs.com.tw/billchung/2012/01/20/66860


    Ader

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:28
    2019年12月10日 下午 12:17
  •  'SerialPort Data Receive Append Safe Thread
        Private Sub AppendSafeThread()
            Dim Rcount As Integer
            Dim Buffer() As Byte
            Rcount = SerialPort1.BytesToRead
            ReDim Buffer(Rcount - 1)
            SerialPort1.Read(Buffer, 0, Rcount)
            AppendReceive(Buffer)
        End Sub
        'Change Receiver Mode Universal to Binary Mode
        Private Sub ChangeRVMode()
            If rbReceive_V.Checked Then
                rbReceive_B.Checked = True 這一行說是不同執行緒, 那是怎麼回事?
                OldMode_R = 1
            End If
        End Sub
        'SerialPort Data Received must Call Receive Thread make safely Receive
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            ChangeRVMode()
            Me.AppendThread = New Thread(New ThreadStart(AddressOf Me.AppendSafeThread))
            Me.AppendThread.Start()
        End Sub

    TechNet 論壇主要討論企業 IT 相關產品及技術,
    如有程式開發相關問題請移駕至 MSDN 論壇

    本文已協助移動


    蘇老碎碎念
    資訊無涯,回頭已不見岸
    Facebook - 微軟台灣官方論壇愛好者俱樂部

    論壇不是神壇,沒人會通靈知道問題狀況
    請正確簡述標題及詳述狀況
    如何在論壇正確發問,可以參考iThome的文章:
    如何問到我要的答案

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:27
    2019年12月10日 下午 02:16
    版主
  • 通常,Main Thread 就是 GDI Thread ,其他都是 Work Thread 。

    WindowMessage -> GDI Thread -> DataReceived (Work Thread A) -> ChangeRVMode/ Thread.Start (A) -> AppendSafeThread (Work Thread B)

    如果你的rbReveive_B是控制項的屬性,則只能被GDI Thread 變更,則你在Thread A 要委派給GDI Thread 進行屬性變更。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 David Lai18 2019年12月11日 上午 02:27
    2019年12月10日 下午 03:24