2016-10-26 13 views
0

Termie(C#版のシロアリ)をvb.netに移植しています。私はC#でこのアプリを使って作業してくれました。しかし、今回は、vb.netアプリケーションに折りたたむ必要があり、アプリケーションがシリアルポートから受け取ったときに「オブジェクトリファレンスがオブジェクトのインスタンスに設定されていません」というエラーが発生しています。vb.net、Termie、スレッド、「オブジェクト参照がオブジェクトのインスタンスに設定されていません」

ここ

Private Sub ReadPort() 

    While _keepReading 
     If _serialPort.IsOpen Then 
      Dim readBuffer As Byte() = New Byte(_serialPort.ReadBufferSize) {} 
      Try 
       ' If there are bytes available on the serial port, 
       ' Read returns up to "count" bytes, but will not block (wait) 
       ' for the remaining bytes. If there are no bytes available 
       ' on the serial port, Read will block until at least one byte 
       ' is available on the port, up until the ReadTimeout milliseconds 
       ' have elapsed, at which time a TimeoutException will be thrown. 
       Dim count As Integer = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize) 
       Dim SerialIn As [String] = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count) 
       DataReceived(SerialIn) 

      Catch generatedExceptionName As TimeoutException 
      Catch ex As Exception 
       MsgBox(ex.Message) 
      End Try 
     Else 
      Dim waitTime As New TimeSpan(0, 0, 0, 0, 50) 
      Thread.Sleep(waitTime) 
     End If 
    End While 
End Sub` 

DataReceived(SerialIn)失敗したコードだと、エラーがスローされます。ここで

は、私がそうな何かを明らかに届かないが、スレッドの作成との相互作用の様々な味が私にはあいまいであり、私は私の過去を取得することができていないデリゲート

'begin Observer pattern 
Public Delegate Sub EventHandler(param As String) 
Public DataReceived As EventHandler 
Public StatusChanged As EventHandler 

として指定しています方法ですエラー。

これは、ユビキタスな「オブジェクト参照が設定されていません...」というエラーが発生する理由です。そして、はい、私はオブジェクトが設定されていないことを取得します。 ;)ここで

私が呼び出そうとしてるものです:終ら以来

Friend Delegate Sub StringDelegate(ByVal strData As String) 

Public Sub ReceiveFromServer(ByVal strDataIn As String) 

    If Me.InvokeRequired() Then 
     ' InvokeRequired: We're running on the background thread. Invoke the delegate. 
     Me.Invoke(New StringDelegate(AddressOf ReceiveFromServer), New Object() {strDataIn}) 
    Else 
     Dim i As Integer = 0 
    End If 

End Sub 
+0

あなた自身のオブザーバーパターンを実装しないでください。代わりに 'Event'キーワードを使用してRaiseEventを呼び出すと、NREを取得しません。または、独自のスレッドを作成する代わりに、組み込みのSerialPort.DataReceivedイベントを使用します。木が森に落ちていて、その周りに誰もいない場合は、音を出さない場合でも、誰かにイベントを購読させるつもりです。 –

+0

それは合理的で、それはそれに来るかもしれません。しかし、私は、一貫性を維持するために元のC#コードのパラダイムの中で作業しようとしています。どこか、どうにかして、C#からvb.netへの移植に問題が生じました。それ以外はすべて動作します。データの送信は問題なく、プログラムはデータを受信します。唯一の問題は、 "リスニング"がスレッドで発生するので、アプリケーションの残りの部分にそれを渡すことです。アイデアをありがとう。 – jbmckim

+0

ここには「パラダイム」はありませんが、これはプログラマーがイベントを理解していない人が書いたものです。典型的なCodeproject.comの問題btw。 DataReceivedの「イベント」を購読し、受け取ったデータで何かを行う関連コードは表示されていませんが、それは私たちの助けにはなりません。たぶんあなたはそれを書いていない、問題の最も明白な説明。 –

答えて

0

は最終的に、私は先に行って、デリゲートの実装を再構築し、一貫性を維持する切り札。シリアルポート上のルーチンリスニングは次のようになります。

Public Delegate Sub DataReceived(ByVal MsgString As String) 
Public Delegate Sub EventHandler(param As String) 

(EventHandlerが他の場所で使用されている)

そして:

Private Sub ReadPort() 

    Dim MessagePump As DataReceived 
    MessagePump = AddressOf Serial_Port_UI.ReceiveFromServer 

    While _keepReading 
     If _serialPort.IsOpen Then 
      Dim readBuffer As Byte() = New Byte(_serialPort.ReadBufferSize) {} 
      Try 
       ' If there are bytes available on the serial port, 
       ' Read returns up to "count" bytes, but will not block (wait) 
       ' for the remaining bytes. If there are no bytes available 
       ' on the serial port, Read will block until at least one byte 
       ' is available on the port, up until the ReadTimeout milliseconds 
       ' have elapsed, at which time a TimeoutException will be thrown. 
       Dim count As Integer = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize) 
       Dim SerialIn As [String] = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count) 
       MessagePump.Invoke(SerialIn) 
       'DataReceived(SerialIn) 

      Catch generatedExceptionName As TimeoutException 
      Catch ex As Exception 
       MsgBox(ex.Message) 
      End Try 
     Else 
      Dim waitTime As New TimeSpan(0, 0, 0, 0, 50) 
      Thread.Sleep(waitTime) 
     End If 
    End While 
End Sub 

をすべてがターゲットフォーム/クラスに希望の文字列を生成し、このこのように:

Public Delegate Sub StringDelegate(ByVal strData As String) 

Public Sub ReceiveFromServer(ByVal strDataIn As String) 

    If Me.InvokeRequired() Then 
     ' InvokeRequired: We're running on the background thread. Invoke the delegate. 
     Me.Invoke(New StringDelegate(AddressOf ReceiveFromServer), New Object() {strDataIn}) 
    Else 
     Dim i As Integer = 0 
    End If 

End Sub 

ありがとうHans for the help。

関連する問題