Solved

AsyncCallback thread terminates and code does not return to main app

Posted on 2004-09-07
6
324 Views
Last Modified: 2008-01-09
Hi Experts,
Im writing an e-mail app in vb.net to receive specific e-mails and decode a hex attachment in the e-mail.
Originally i found an e-mail app for vb6 which works great (using winsock). so in my infinite wisdom decided to do the whole thing in vb.net.
I have written a class that creates a socket then uses the Async send and receive functions, whose events are picked up by corresponding delegates.
I get so far in the main app where i receive the first part of an e-mail, my OnDataArrival event is fired by the receive callback delegate, then half way through the code in the OnDataArrival function the  receive callback delegate takes back control and the code in rest of the  OnDataArrival function does not execute and program flow ceases.
Now I have seen in examples that you can use the ManualResetEvent to stop the thread but this does not seem to help.

Here is the class

Public Class vbnetsock
    Public Event OnDataArrival(ByVal Message As String)
    Public Shared allDone As New ManualResetEvent(False)
    Dim IPEP As IPEndPoint
    Dim IPHE As IPHostEntry
    Dim mySocket As Socket
    Dim ascii As New ASCIIEncoding
    Const bufferSize As Integer = 1024

    Public Sub Connect(ByVal host As String, ByVal port As Integer)

        allDone.Reset()
        IPHE = Dns.Resolve(host)
        IPEP = New IPEndPoint(IPHE.AddressList(0), 110)
        mySocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        mySocket.BeginConnect(IPEP, New AsyncCallback(AddressOf Connect_Callback), mySocket)
        allDone.WaitOne()

    End Sub

    Private Sub Connect_Callback(ByVal ar As IAsyncResult)

        allDone.Set()
        mySocket = CType(ar.AsyncState, Socket)
        mySocket.EndConnect(ar)
        Dim buff(bufferSize) As Byte
        mySocket.BeginReceive(buff, 0, buff.Length, 0, New AsyncCallback(AddressOf Receive_CallBack), buff)

    End Sub

    Private Sub Receive_CallBack(ByVal ar As IAsyncResult)

        Dim bytes() As Byte = ar.AsyncState
        Dim numBytes As Int32 = mySocket.EndReceive(ar)
        'If numBytes > 0 Then
        ReDim Preserve bytes(numBytes - 1)
        Dim received As String = ascii.GetString(bytes)
        RaiseEvent OnDataArrival(received)

    End Sub

    Public Sub Send(ByVal message As String)

        Dim buff As Byte() = Encoding.ASCII.GetBytes(message)
        mySocket.BeginSend(buff, 0, buff.Length, SocketFlags.None, New AsyncCallback(AddressOf Send_CallBack), mySocket)

    End Sub

    Private Sub Send_CallBack(ByVal ar As IAsyncResult)

        mySocket = CType(ar.AsyncState, Socket)
        mySocket.EndSend(ar)
        Dim buff(bufferSize) As Byte
        mySocket.BeginReceive(buff, 0, buff.Length, 0, New AsyncCallback(AddressOf Receive_CallBack), buff)

    End Sub
    Public Sub close()

        mySocket.Close()

    End Sub

End Class

Please correct any prgramming foobars i have made as im still quite new to vb.net
Any help would be most appreciated.
0
Comment
Question by:Yrag1
  • 2
6 Comments
 
LVL 7

Expert Comment

by:vbwizardry
ID: 12002331
In your place I would use asynchronous event (call back). Also use a SyncLock in the events body that way it will force thread to wait for the previous one to complete.
Sub …_OnDataArrival(ByVal Message As String)
SyncLock Me
      ‘Your code here
End SyncLock
End Sub
Try it
0
 
LVL 1

Author Comment

by:Yrag1
ID: 12008592
I still does not work and ends in the same place.
What do you mean by "asynchronous event (call back) "?
0
 
LVL 7

Accepted Solution

by:
vbwizardry earned 400 total points
ID: 12019858
Try this code: I have changed it a litle.

Public Class VBNetSock
    Public Event OnDataArrival(ByVal Message As String)
    Private Shared allDone As New ManualResetEvent(False)
    Private mySocket As Socket
    Private Const bufferSize As Integer = 1024
    Private buffer(bufferSize) As Byte

    Public Sub Connect(ByVal host As String, ByVal port As Integer, Optional ByVal timeout As Integer = 0)

        allDone.Reset()
        mySocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        Dim ep As IPEndPoint = New IPEndPoint(Dns.Resolve(host).AddressList(0), port)
        mySocket.BeginConnect(ep, New AsyncCallback(AddressOf Connect_Callback), mySocket)
        allDone.WaitOne(timeout, False)
    End Sub

    Private Sub Connect_Callback(ByVal ar As IAsyncResult)
        Try
            allDone.Set()
            Dim remote As Socket = ar.AsyncState
            remote.EndConnect(ar)
            remote.BeginReceive(buffer, 0, buffer.Length, 0, New AsyncCallback(AddressOf Receive_CallBack), remote)
        Catch ex As Exception
            Debug.WriteLine(ex.ToString())
        End Try
    End Sub

    Private Sub Receive_CallBack(ByVal ar As IAsyncResult)
        Try
            Dim remote As Socket = ar.AsyncState
            Dim rtVal As Int32 = remote.EndReceive(ar)
            RaiseEvent OnDataArrival(Encoding.ASCII.GetString(buffer, 0, rtVal))
        Catch ex As Exception
            Debug.WriteLine(ex.ToString())
        End Try
    End Sub

    Public Sub Send(ByVal message As String)
        Try
            If message.LastIndexOf(vbCrLf) <> message.Length - 2 Then
                message &= vbCrLf
            End If
            Dim buffer As Byte() = Encoding.ASCII.GetBytes(message)
            mySocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, New AsyncCallback(AddressOf Send_CallBack), mySocket)
        Catch ex As Exception
            Debug.WriteLine(ex.ToString())
        End Try
    End Sub

    Private Sub Send_CallBack(ByVal ar As IAsyncResult)
        Try
            Dim client As Socket = ar.AsyncState
            client.EndSend(ar)
            client.BeginReceive(buffer, 0, buffer.Length, 0, New AsyncCallback(AddressOf Receive_CallBack), client)
        Catch ex As Exception
            Debug.WriteLine(ex.ToString())
        End Try
    End Sub

    Public Sub close()
        mySocket.Close()
    End Sub

End Class
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

863 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now