Results 1 to 23 of 23

Thread: [VB6] - Class for waiting asynchronous kernel objects.

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,203

    [VB6] - Asynchronous waiting for kernel objects.

    Hello everyone.

    This class allows to wait for Windows kernel objects and generate an event when an object switches to the signaled state or a timeout has elapsed.

    The class has 3 methods: vbWaitForSingleObject, vbWaitForMultipleObjects and Abort. The first two methods are the analogs of the corresponding WINAPI functions WaitForSingleObject and WaitForMultipleObjects.

    As soon as an object (or all the objects) changes the state to signaled the event OnWait is fired. The arguments of the events contains the event handle (or the pointer to the handles) and the returned value. Abort method allows to break any pending waiting operation. It can either returns immediately or wait until the request will be processed.

    The class also contains property IsActive which shows if there is an active waiting operation.

    Github repository.
    Last edited by The trick; Nov 20th, 2021 at 03:32 PM. Reason: New version

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,203

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    [not relevant]
    Last edited by The trick; Nov 20th, 2021 at 03:29 PM.

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,203

    Demonstration of monitoring the file operation.

    [not relevant]
    Last edited by The trick; Nov 20th, 2021 at 03:29 PM.

  4. #4

  5. #5

  6. #6
    Lively Member
    Join Date
    Oct 2008
    Posts
    111

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Hi
    in your class i see a function
    Code:
    Function vbWaitForMultipleObjects
    When you use this function?

    For WaitableTimer: you need to create multiple instances of the same class for handle multiple timer events?

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,203

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Quote Originally Posted by Nanni View Post
    Hi
    in your class i see a function
    Code:
    Function vbWaitForMultipleObjects
    When you use this function?
    This function is the analog of WinAPI function WaitForMultipleObjects. This function waits for the multiple instances of kernel objects. You can control the behavior of function in order to wait for any object from the list or wait for all objects from the list.
    Quote Originally Posted by Nanni View Post
    For WaitableTimer: you need to create multiple instances of the same class for handle multiple timer events?
    Not necessary. You can either create the multiple instances for each event or create the single instance and wait them by vbWaitForMultipleObjects. Just create the array of the handles and pass it (more precisely the address of the first element) to the second parameter of the method.

  8. #8
    Lively Member
    Join Date
    Oct 2008
    Posts
    111

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Hi
    I tweaked in this way:

    Code:
    Dim hTimer()          As Long
    Dim EventCount      As Long
    
    Private Sub Form_Load()
        Set tmr = New clsTrickWait
        EventCount = -1
     txtTimeClock = Now
    End Sub
    
    Private Sub cmdSetTimer_Click()
        On Error GoTo Cancel
        
        Dim Dat     As Date
        Dim st(8)   As Integer
        Dim ft      As Currency
        Dim lt      As Currency
        
        ' // To system time
        Dat = CDate(txtTimeClock)
        VariantTimeToSystemTime Dat, st(0)
        SystemTimeToFileTime st(0), lt
        LocalFileTimeToFileTime lt, ft
        
        EventCount = EventCount + 1 
        
        ReDim Preserve hTimer(EventCount)
        
    '     // Create the waitable timer
        hTimer(EventCount) = CreateWaitableTimer(ByVal 0&, False, 0)
        
    ' // Set the waitable timer
        SetWaitableTimer hTimer(EventCount), VarPtr(ft), 0, 0, 0, 0
     Exit Sub
        
    Cancel:
        
        MsgBox "Error", vbExclamation
        
    End Sub
    
    Private Sub cmdArm_Click()
    tmr.vbWaitForMultipleObjects EventCount, hTimer(0), 0&, INFINITE
    End Sub
    ..but crash when I click cmdArm button

    I'm doing something wrong?

  9. #9

  10. #10
    Lively Member
    Join Date
    Oct 2008
    Posts
    111

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Hi
    I made change in code
    Code:
    tmr.vbWaitForMultipleObjects NumEvent, VarPtr(hTimer(0)), 0&, INFINITE
    but always crash.
    Also looking at your class in
    Code:
    Public Function Abort
    I see only reference to
    Code:
    WaitForSingleObject
    If you want check, I have enclosed my test project.

    Thanks
    Attached Files Attached Files

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,203

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Your error is:
    Code:
    Private Sub cmdArm_Click()
        tmr.vbWaitForMultipleObjects EventCount + 1, VarPtr(hTimer(0)), 0&, INFINITE
    End Sub
    I guess you don't understand the meaning of the WaitForMultipleObjects function.
    Look the small example:
    Code:
    Dim timersCount      As Long
    
    Private Sub Form_Load()
        Dim i As Long
        Dim d As Date
        
        Set tmr = New clsTrickWait
        
        ' // Add 10 timers with the difference at 5 seconds
        d = Now
        
        For i = 0 To 9
            d = DateAdd("s", 5, d)
            AddTimer d
        Next
        
        ' // Launch the waiting
        tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE
        
    End Sub
    
    ' // This procedure add the timer to the array
    Private Sub AddTimer(datTime As Date)
        Dim st(8)   As Integer
        Dim ft      As Currency
        Dim lt      As Currency
        
        timersCount = timersCount + 1
        ReDim Preserve hTimer(timersCount - 1)
        hTimer(timersCount - 1) = CreateWaitableTimer(ByVal 0&, False, 0)
        VariantTimeToSystemTime datTime, st(0)
        SystemTimeToFileTime st(0), lt
        LocalFileTimeToFileTime lt, ft
        SetWaitableTimer hTimer(timersCount - 1), VarPtr(ft), 0, 0, 0, 0
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        Dim i As Long
        For i = 0 To UBound(hTimer)
        CloseHandle hTimer(i)
        Next i
    End Sub
    
    ' // Event occurs after the tick of the waitable timer
    Private Sub tmr_OnWait(ByVal Handle As Long, ByVal Result As Long)
        
        If Result < timersCount And Result >= 0 Then
            ' // Remove timer from array, just send it to the end of the array and decrement number of timers
            Dim i As Long
            Dim t As Long
            
            timersCount = timersCount - 1
            t = hTimer(Result)
            
            For i = Result To timersCount - 1
                hTimer(i) = hTimer(i + 1)
            Next
            
            hTimer(timersCount) = t
            
        End If
        
        ' // Run wait again
        tmr.Abort
        tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE
    
        MsgBox "Timer event." & vbNewLine & "Handle = " & t
        
    End Sub

  12. #12
    Lively Member
    Join Date
    Oct 2008
    Posts
    111

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Hi
    Thanks for example.
    Now I have learned how to use WaitForMultipleObjects

  13. #13
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Quote Originally Posted by The trick View Post
    Your error is:
    Code:
    Private Sub cmdArm_Click()
        tmr.vbWaitForMultipleObjects EventCount + 1, VarPtr(hTimer(0)), 0&, INFINITE
    End Sub
    I guess you don't understand the meaning of the WaitForMultipleObjects function.
    Look the small example:
    Code:
    Dim timersCount      As Long
    
    Private Sub Form_Load()
        Dim i As Long
        Dim d As Date
        
        Set tmr = New clsTrickWait
        
        ' // Add 10 timers with the difference at 5 seconds
        d = Now
        
        For i = 0 To 9
            d = DateAdd("s", 5, d)
            AddTimer d
        Next
        
        ' // Launch the waiting
        tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE
        
    End Sub
    
    ' // This procedure add the timer to the array
    Private Sub AddTimer(datTime As Date)
        Dim st(8)   As Integer
        Dim ft      As Currency
        Dim lt      As Currency
        
        timersCount = timersCount + 1
        ReDim Preserve hTimer(timersCount - 1)
        hTimer(timersCount - 1) = CreateWaitableTimer(ByVal 0&, False, 0)
        VariantTimeToSystemTime datTime, st(0)
        SystemTimeToFileTime st(0), lt
        LocalFileTimeToFileTime lt, ft
        SetWaitableTimer hTimer(timersCount - 1), VarPtr(ft), 0, 0, 0, 0
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        Dim i As Long
        For i = 0 To UBound(hTimer)
        CloseHandle hTimer(i)
        Next i
    End Sub
    
    ' // Event occurs after the tick of the waitable timer
    Private Sub tmr_OnWait(ByVal Handle As Long, ByVal Result As Long)
        
        If Result < timersCount And Result >= 0 Then
            ' // Remove timer from array, just send it to the end of the array and decrement number of timers
            Dim i As Long
            Dim t As Long
            
            timersCount = timersCount - 1
            t = hTimer(Result)
            
            For i = Result To timersCount - 1
                hTimer(i) = hTimer(i + 1)
            Next
            
            hTimer(timersCount) = t
            
        End If
        
        ' // Run wait again
        tmr.Abort
        tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE
    
        MsgBox "Timer event." & vbNewLine & "Handle = " & t
        
    End Sub
    have some questions
    “If Result < timersCount And Result >= 0 Then”
    result always > timersCount?Name:  a.png
Views: 3865
Size:  27.7 KB
    how error?

  14. #14

  15. #15
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    because 258,can not changed,how can load if~end if function code

  16. #16
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Name:  QQ图片20151019102350.jpg
Views: 3554
Size:  27.6 KB

  17. #17

  18. #18
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    the code is you
    Dim timersCount As Long

    Private Sub Form_Load()
    Dim i As Long
    Dim d As Date

    Set tmr = New clsTrickWait

    ' // Add 10 timers with the difference at 5 seconds
    d = Now

    For i = 0 To 9
    d = DateAdd("s", 5, d)
    AddTimer d
    Next

    ' // Launch the waiting
    tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE

    End Sub

    ' // This procedure add the timer to the array
    Private Sub AddTimer(datTime As Date)
    Dim st(8) As Integer
    Dim ft As Currency
    Dim lt As Currency

    timersCount = timersCount + 1
    ReDim Preserve hTimer(timersCount - 1)
    hTimer(timersCount - 1) = CreateWaitableTimer(ByVal 0&, False, 0)
    VariantTimeToSystemTime datTime, st(0)
    SystemTimeToFileTime st(0), lt
    LocalFileTimeToFileTime lt, ft
    SetWaitableTimer hTimer(timersCount - 1), VarPtr(ft), 0, 0, 0, 0
    End Sub

    Private Sub Form_Unload(Cancel As Integer)
    Dim i As Long
    For i = 0 To UBound(hTimer)
    CloseHandle hTimer(i)
    Next i
    End Sub

    ' // Event occurs after the tick of the waitable timer
    Private Sub tmr_OnWait(ByVal Handle As Long, ByVal Result As Long)

    If Result < timersCount And Result >= 0 Then
    ' // Remove timer from array, just send it to the end of the array and decrement number of timers
    Dim i As Long
    Dim t As Long

    timersCount = timersCount - 1
    t = hTimer(Result)

    For i = Result To timersCount - 1
    hTimer(i) = hTimer(i + 1)
    Next

    hTimer(timersCount) = t

    End If

    ' // Run wait again
    tmr.Abort
    tmr.vbWaitForMultipleObjects timersCount, VarPtr(hTimer(0)), 0, INFINITE

    MsgBox "Timer event." & vbNewLine & "Handle = " & t

    End Sub

  19. #19
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    if i used this code in IDE,have no error ,but if i make the code tO exe,the error can happen
    d = DateAdd("s", 5, d)
    AddTimer d
    Next

  20. #20
    Lively Member
    Join Date
    Feb 2006
    Posts
    82

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    I use clsTrickWait.cls to monitoring the file operation in a folder but i have a problem.....

    1. Start folder monitor
    2. Start Copy a very large file to folder
    3. Event FILE_ACTION_ADDED appear when file start to write on disk.
    4. After a time finish copying file (write on disk finish)
    5. .......HOW CAN I DETECT MOMENT WHEN FILE FINISHING COPY (WRITE DO DISK).....?

  21. #21

  22. #22
    Lively Member
    Join Date
    Feb 2006
    Posts
    82

    Re: [VB6] - Class for waiting asynchronous kernel objects.

    Quote Originally Posted by The trick View Post
    Also you should use the FILE_NOTIFY_CHANGE_LAST_WRITE flag in ReadDirectoryChangesW.

    ... Thanks and i found this...
    https://www.desaware.com/tech/filemonitoring.aspx
    Last edited by cliv; Jan 22nd, 2016 at 02:22 AM.

  23. #23

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width