none
Waiting an event RRS feed

  • Question

  • During code execution, if i have to wait for an event to hapen (serial data to arrive from a PC port for example), i cannot use: 

    While (condition)

    end while

    beacouse i could not use buttons on form and it seems that, as soon as entering this cicle, microprocessor does not even complete what it was doing. If data do not arrive, i have to reset the application. Even a timer, when entering the while loop, does not work anymore.

    If I use: 

    do

          if condition=true then

               exit loop

           end if

           application.doevents

    loop

    all works well.

    So my question is why this difference? Why this important feature is not explained in microsoft reference?

    Regards






    Friday, February 21, 2020 9:40 AM

All replies

  • You can see samples like : VB.Net: Serial Port Data Reception
    Friday, February 21, 2020 9:55 AM
  • Thaks fro your reply Castorix31.

    I receive serial data using event of SerialPort : DataReceived.

    My question is why this difference of the 2 loops, and if there is another way to wait an event.

    Regards

    Friday, February 21, 2020 10:54 AM
  • The sample shows a way, with background threads
    Friday, February 21, 2020 10:56 AM
  • During code execution, if i have to wait for an event to hapen (serial data to arrive from a PC port for example), i cannot use: 

    While (condition)

    end while

    beacouse i could not use buttons on form and it seems that, as soon as entering this cicle, microprocessor does not even complete what it was doing.

    This is not the same as "waiting for an event." This is instead "blocking the application thread indefinitely." As such your data I/O events are never occurring because the application is doing nothing but spinning this loop. That is unless your 'condition' was something like While (Data NOT Available On Port). So the last sentence quoted above answers its own question. You are actively preventing the application from doing anything else.

    If I use: 

    do

          if condition=true then

               exit loop

           end if

           application.doevents

    loop

    all works well.

    So my question is why this difference? Why this important feature is not explained in microsoft reference?

    Regards

    I bolded the only relevant part. Application.DoEvents() is kind of a funky callout or return-with-assurance-of-rereturn-to-here type of function. This isn't documented well because it's more or less assumed that DotNET Developers will have some experience writing Windows Applications in lower level languages like C and C++, where you'd have to write your own "message pump" which is how the Operating System tells the application stuff like "user clicked a button" or "data received on I/O port."

    In a DotNET application that message pump is handled for you, in the background. It runs whenever your own code isn't doing anything, so when your code is blocking with a While loop, it doesn't run. Your call to Application.DoEvents() immediately calls that background/done-for-you message pump at which point button clicks and data I/O notifications are received and delegated to event handlers before execution returns to the next line in the While (meaning the line that occurs after the call to DoEvents()). It's just pausing your own custom code long enough to let the OS and the Application do their regular business with each other.

    Friday, February 21, 2020 11:09 AM
  • You could use an asynchronous method. Below the language extension does a Do While to read from a serial port. Optionally to cancel you could use a CancellationToken.

    Public Module SerialPortExtensions
        <Runtime.CompilerServices.Extension>
        Public Async Function ReadAsync(
            serialPort As SerialPort,
            buffer() As Byte,
            offset As Integer,
            count As Integer) As Task
    
            Dim bytesToRead = count
            Dim temp = New Byte(count - 1) {}
    
            Do While bytesToRead > 0
    
                Dim readBytes = Await serialPort.BaseStream.ReadAsync(temp, 0, bytesToRead)
                Array.Copy(temp, 0, buffer, offset + count - bytesToRead, readBytes)
                bytesToRead -= readBytes
    
            Loop
    
        End Function
        <Runtime.CompilerServices.Extension>
        Public Async Function ReadAsync(serialPort As SerialPort, count As Integer) As Task(Of Byte())
    
            Dim buffer = New Byte(count - 1) {}
            Await serialPort.ReadAsync(buffer, 0, count)
    
            Return buffer
    
        End Function
    End Module

    Implement

    '
    ' serialPort variable is defined as a private variable
    '
    Public Async Sub Work()
        Try
            Dim data = Await serialPort.ReadAsync(5)
            DoStuff(data)
        Catch exception As Exception
            Trace.WriteLine(Exception.Message)
        End Try
    End Sub


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Friday, February 21, 2020 1:21 PM
    Moderator
  • You can see samples like : VB.Net: Serial Port Data Reception
    Long ago, in a ......

    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Friday, February 21, 2020 2:47 PM