Solved

How to get data from IAsyncResult to a form?

Posted on 2011-09-16
6
868 Views
Last Modified: 2013-11-08
I wrote a tcpClient that speaks to a server over a telnet connection.

The code below sends a packet (in this case, an authentication packet to login), and then does an asynchronus read to the callback.

Public Sub SendPacket(ByRef Packet As AMIPacket)
        Dim myWriteBuffer As NetworkStream = _session.GetStream
        If myWriteBuffer.CanWrite Then
            myWriteBuffer.BeginWrite(Packet.RenderPacket, 0, Packet.RenderPacket.Length, callBack, myWriteBuffer)
        End If
    End Sub

Open in new window


The problem is: the function that executes the asychnous operation parses the return information, which I need to pass to a textbox control on the form so I can log the communications. I get the error:


Cross-thread operation not valid: Control 'txtLog' accessed from a thread other than the thread it was created on.
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll


How do I get the parsed data that is returned from the server passed to the form?
0
Comment
Question by:DrDamnit
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 36

Expert Comment

by:Miguel Oz
ID: 36552963
You need to interact with your GUI in a thread safe way, check:
http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

and look for the SetText method implementation.
0
 
LVL 4

Expert Comment

by:guramrit
ID: 36553052
Yo've posted incomplete information about code, or different code for different problem.
By the way BeginWrite doesn't return any value, but you can complete async operation using EndWrite(IAsyncResult).
And you can prevent cross thread errors to occur using txtLog.BeginInvoke function. If you need code then post your code where you pass value to a textbox control (txtLog).
0
 
LVL 13

Expert Comment

by:Corey2
ID: 36553122
You need to invoke a delegate on the thread the control was created on, similar to below.

regards,

Corey

Public Sub Callback(ByVal ar As IAsyncResult)
        If TextBox1.InvokeRequired Then
            'create delegate
            Dim del As New AsyncCallback(AddressOf Callback)
            'invoke delegate on propper thread 
            TextBox1.BeginInvoke(del, New Object() {ar})
            Exit Sub
        Else
            'it is safe to update textbox if InvokeRequired returns false
            TextBox1.Text = ar.CompletedSynchronously
        End If
    End Sub

Open in new window

0
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 
LVL 32

Author Comment

by:DrDamnit
ID: 36557113
The code that is running in a separate thread (that apparently needs to be a delegate or delegated) is:

 
Public Function ProcessInboundPackets(ByVal ar As IAsyncResult) As Boolean
        Dim message(1024) As Byte
        Dim buffer(1024) As Byte
        Dim strBuffer As String
        Dim Response() As String
        Dim myNetworkStream As NetworkStream = CType(ar.AsyncState, NetworkStream)
        Dim i As Integer = 0
        Dim c As Integer = 0

        While myNetworkStream.CanRead
            ReDim buffer(1024)

            'Find the first null element in the message
            For i = 0 To message.Length
                If message(i) = 0 Then c = i
                Exit For
            Next
            'Get the inbound stream
            myNetworkStream.Read(buffer, 0, buffer.Length)

            'Copy bytes into the message until we get 13 10 13 10 or 0
            For i = 0 To buffer.Length - 1
                'Is there is enough room for a crlf crlf
                If i + 3 <= buffer.Length - 1 Then
                    'Is this the termination?
                    If buffer(i) = 13 And buffer(i + 1) = 10 And buffer(i + 2) = 13 And buffer(i + 3) = 10 Then
                        'we have reached the end. Write them to the message, and send the message for processing.
                        message(i + c) = buffer(i)
                        'Send the message for processing
                        strBuffer = "**********" & vbCrLf & System.Text.Encoding.UTF8.GetString(message).Trim & vbCrLf & "**********"
                        RaiseEvent Log(strBuffer)
                        'Check to see if we win.
                        Response = strBuffer.Split(":")
                        If Response(1) = "Authentication accepted" Then
                            Return True
                        Else
                            Return False
                        End If
                        'Reset the message buffer
                        ReDim message(1024)
                    Else
                        'This is not the end fo the message. Keep writing to the message buffer
                        message(i + c) = buffer(i)
                    End If
                End If
            Next

            'ShowPacket(buffer)
        End While

    End Function

Open in new window


This code runs in a class called clsAMI.vb. In order to pass the information back to the form, I am trying to use RaiseEvent() (see line 31), which is obviously failing.

How do I make this a delegate?

PS. The form code that fires for teh RaiseEvent() is this:

 
Private Sub AMI_Log(ByVal sMessage As String) Handles AMI.Log
        Dim strBuffer
        strBuffer = txtLog.Text
        strBuffer = strBuffer & vbCrLf & sMessage & vbCrLf
        Try
            txtLog.Text = strBuffer
        Catch ex As Exception
            Debug.Print(strBuffer)
            Debug.Print(ex.Message)
        End Try

        txtLog.SelectionStart = txtLog.Text.Length

    End Sub

Open in new window

0
 
LVL 13

Accepted Solution

by:
Corey2 earned 500 total points
ID: 36557177
The attached code should do the trick.  You just have to declare a delegate with the same signature as the method you need it to delegate.

Corey
Delegate Sub AMI_LogDel (byval sMessage as string) 

Private Sub AMI_Log(ByVal sMessage As String) Handles AMI.Log
        
        If txtLog.InvokeRequired then
            'create delegate
            Dim del As New AMI_LogDel(AddressOf AMI_Log)
            'invoke delegate on propper thread 
            txtLog.BeginInvoke(del, New Object() {sMessage})
            Exit Sub
        else

        Dim strBuffer
        strBuffer = txtLog.Text
        strBuffer = strBuffer & vbCrLf & sMessage & vbCrLf
        Try
            txtLog.Text = strBuffer
        Catch ex As Exception
            Debug.Print(strBuffer)
            Debug.Print(ex.Message)
        End Try

        txtLog.SelectionStart = txtLog.Text.Length
       end if
    End Sub

Open in new window

0
 
LVL 32

Author Closing Comment

by:DrDamnit
ID: 36557467
So much simlier than I was making it! Thank You!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question