Search code examples
vb.nettcpwait

Wait unit an event is raised


I'm trying to make a code that waits until an event is raised. I used the answer in this answer page for Tcp communication. The event PacketReceived will be raised when a packet is received.

Private Sub FooBar()
    'Send some Tcp Message here`

    'Wait until a reply is received here

    'Execute some code when reply is received

End Sub

This is code Sends the filename and what's the file for. It lacks of file existence checking

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim t = New Thread(AddressOf SendFile)
        Dim f = New FileAndData
        f.FileList = SlideShowItems
        f.FileType = "tempSlideShowImage"
        t.Start(f)
    End Sub

    Private Sub SendFile(obj As Object)
        Dim fD = CType(obj, FileAndData)
        For Each item In fD.FileList.Items
            Dim fileIn As New FileStream(item, FileMode.Open)
            Const chunkSize = 10485760

            Dim messageFileNamePkt As New TcpMessagePacket(Encoding.Default.GetBytes(Path.GetFileName(item)), TcpMessagePacket.PacketHeader.Filename)
            messageFileNamePkt.Send(_etcClient.Client) 'Send file name

            Dim messageFiletype As New TcpMessagePacket(Encoding.Default.GetBytes(fD.FileType), TcpMessagePacket.PacketHeader.Filetype)
            messageFiletype.Send(_etcClient.Client) 'Send file type

            'Wait here for reply if for file existence

            While fileIn.Position < fileIn.Length
                Dim bytes(chunkSize) As Byte
                If fileIn.Length - fileIn.Position < bytes.Length Then
                    ReDim bytes(fileIn.Length - fileIn.Position - 1)
                End If
                fileIn.Read(bytes, 0, bytes.Length)

                Dim messageFilePkt As New TcpMessagePacket(bytes, TcpMessagePacket.PacketHeader.FileData)
                messageFilePkt.Send(_etcClient.Client) 'Send file chunks

            End While

            fileIn.Close()
            Dim messageFileEnd As New TcpMessagePacket(Encoding.Default.GetBytes(""), TcpMessagePacket.PacketHeader.TransferComplete)
            messageFileEnd.Send(_etcClient.Client) 'Send transfer complete

        Next
    End Sub

Public Class FileAndData
    Public FileList As ListBox
    Public FileType As String
End Class

And this is the handler for the reply

    Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles _etcClient.PacketReceived
    End Sub

Solution

  • Use ManualResetEvent. Ex.

    Imports System.Threading
    Module Module1
        Private ReadOnly WaitEvent As New ManualResetEvent(True)
        Sub Main()
            For i = 1 To 100
                WaitEvent.WaitOne() 'This is like a door. It's open because of ManualResetEvent(True)
                If i = 50 Then
                    WaitEvent.Reset() 'This closes the door
                End If
                Console.WriteLine(i)
            Next
            Console.Read()
        End Sub
        Private Sub SetTheEventWhenCalled()
            WaitEvent.Set() 'This on the other hand, Opens the door
        End Sub
    End Module