Solved

AsyncCallback thread terminates and code does not return to main app

Posted on 2004-09-07
6
328 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
[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
  • 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

Independent Software Vendors: 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

Suggested Solutions

Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

740 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