Solved

AsyncCallback thread terminates and code does not return to main app

Posted on 2004-09-07
6
326 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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
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.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

791 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