Page 1 of 3 123 LastLast
Results 1 to 40 of 113

Thread: VB Multithread Library (Generic Multithreading)

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    VB Multithread Library (Generic Multithreading)

    This is a Ax-DLL (VBMThread11.DLL) for generic multithreading in VB6.

    Current version: 1.1.2

    There is only one public creatable component, the Thread class.
    The Thread class is interface driven and once created the new thread's main function is fired in the BackgroundProcedure event.
    In this event the background work will be done, as it will not lock or freeze the App.
    But attention is required as showing Forms will crash VB.
    Therefore in the BackgroundProcedure event is a param StatusCallback. (IThreadStatusCallback class)
    By this you can fire an synchronous callback. The background thread will be suspended, the method request is marshaled to the main thread.
    On this StatusCallback event you can safely show forms or report progress.
    It is recommended to access project objects (classes, controls) only in the StatusCallback event.

    Do not debug or use 'App.Path' in the BackgroundProcedure event, doing so will cause a crash. (Unless the DebugMode property was set to True)

    The source code of the project can also be viewed on GitHub.

    Registration-Free (Side-by-side) solution for VBMThread11.DLL can be found here.

    Notes:
    - P-Code will fail. Native compilation is necessary.

    List of revisions:
    Code:
    29-Apr-2017
    - The Thread class is not event driven anymore. All "events" are fired now trough an IThread interface.
    - Included mandatory Owner parameter in the Create method. That owner will receive the IThread events.
      Also included an optional Key parameter that helps to identify multiple threads on the same owner.
    - Renamed event 'AsyncProcedure' to 'BackgroundProcedure' and 'SyncCallback' to 'StatusCallback'.
    - Included event 'Complete' that fires after the thread ran to completion or was canceled.
    - Optional Wait parameter included in the Terminate method.
    - Included the ThreadData class that will be passed along the BackgroundProcedure and Complete event.
    - Included Cancel method. This method sets the CancellationPending property to True in the ThreadData.
      How fast the cancellation is done depends on the code in the background procedure and if the developer respects the cancellation request.
    - Included DebugMode property. If set to True the background thread runs synchronous to the main thread.
      This does allow to safely set breakpoints and perform debugging in the IDE.
    17-Jun-2016
    - Fixed a bug in the Suspended property.
    15-Jun-2016
    - First release.
    Attachment: VBMThread11 Ax-DLL project and a demo project.
    Attached Files Attached Files
    Last edited by Krool; Oct 2nd, 2019 at 09:42 PM.

  2. #2
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Krool View Post
    This is a Ax-DLL (VBMThread10.DLL) for generic multithreading in VB6.

    I know that there are plenty of libraries out there providing exactly this.
    However, I want to share this approach and want to demonstrate how to use it.

    Registration-Free (Side-by-side) is not working on this Ax-DLL. It must be registered normally in order to function.
    No libraries are out there providing a barebones minimal framework that is open source...
    you beat me to it! Very nice. You've done a great many services to the community.
    Last edited by DEXWERX; Jun 16th, 2016 at 10:18 AM.

  3. #3

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by The trick View Post
    Great, but it is the very restricted multithreading, because you can't work with the project specified objects classes/forms/controls/etc.
    When you want to work with project specified objects (classes/forms/controls/etc.) you need to make a SyncCallback.Raise in the AsyncProcedure event.
    In this SyncCallback event you can do everything safely as normal. (it is running on the original main thread)
    In the AsyncProcedure event itself you can work with objects which you do create within the procedure, e.g. CreateObject() or simple project classes.

    Example:
    Code:
    Private Sub BackWorker_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
    ' ...
    SyncCallback.Raise
    End Sub
    
    Private Sub BackWorker_SyncCallback(Argument As Variant)
    CommonDialogPageSetup.ShowPageSetup ' Project object variable access
    End Sub
    So I think this approach makes it quite flexible.
    And it was my goal to make a generic solution which is also simple.
    Last edited by Krool; Dec 18th, 2016 at 10:37 AM.

  5. #5
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by The trick View Post
    Great, but it is the very restricted multithreading, because you can't work with the project specified objects classes/forms/controls/etc. I described the similar approach here.
    Quote Originally Posted by Krool View Post
    So I think this approach makes it quite flexible.
    And it was my goal to make a generic solution which is also simple.
    It's a very simple asyncronous framework.
    It's simple enough for someone to incorporate Trick's methods, as well as add more flexibility or complexity.

    It would be nice for it to be single threaded for testing / IDE debugging, although again that can be added outside of the framework.
    Last edited by DEXWERX; Jun 16th, 2016 at 03:10 PM.

  6. #6
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by DEXWERX View Post
    It's a very simple asyncronous framework.
    Yes. Also, it's very useful for the multithreading newbies and professionals too because it doesn't require the big efforts for understanding. Everything is very simple - Create/Asynch/Synch. Of course there is some issues with parameters but at first time it doesn't matter.
    Quote Originally Posted by DEXWERX View Post
    It's simple enough for someone to incorporate Trick's methods, as well as add more flexibility or complexity.
    I would like to note the few details. The code should have the message loop in order to support the marshaling. For example if a project doesn't contain forms you have to loop message cycle (DoEvents, for example, but it loads a thread it's better use GetMessage/TranslateMessage/DispatchMessage functions). You should wait for the thread termination as well. Optionally, as an user of your library i would want to have the ability of passing a parameter to a thread.
    Quote Originally Posted by DEXWERX View Post
    It would be nice for it to be single threaded for testing / IDE debugging, although again that can be added outside of the framework.
    The Krool approach is quite stable in your example, but it'll crash anyway in IDE. All my methods doesn't work in IDE (except EXE multithreading that works in the main thread). I absolutely have no time to translate my examples to English and public the new projects. In short, that example uses the precompiled DLL and creates the object in the new thread. You have the ability to call a method synchronously and asynchronously and receive the event from this object.

  7. #7
    Addicted Member
    Join Date
    May 2016
    Location
    China
    Posts
    197

    Re: VB Multithread Library (Generic Multithreader)

    Can this be used in the sql server database query?

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Update released.
    Minor bugfix in the Suspended property.
    The DLL in /Bin have been recompiled with binary compatibility.

    Quote Originally Posted by The trick View Post
    Optionally, as an user of your library i would want to have the ability of passing a parameter to a thread.
    You could access the projects variables within the AsyncProcedure event and use this as a passing parameter. But, of course a Param could be included out of the event itself.

    Quote Originally Posted by ChenLin View Post
    Can this be used in the sql server database query?
    If you create the objects within the AsyncProcedure event it should be possible.
    Last edited by Krool; Jun 17th, 2016 at 03:38 PM.

  9. #9
    Lively Member
    Join Date
    Oct 2010
    Posts
    75

    Re: VB Multithread Library (Generic Multithreader)

    Good work.

    Could this DLL be merged with an ActiveX EXE ?

  10. #10
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Kunical View Post
    Good work.

    Could this DLL be merged with an ActiveX EXE ?
    Why would you need this in an ActiveX EXE, considering an ActiveX EXE can use VB6's standard multithreading methods?
    (setting the Threading Model)

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Here is a solution to use the VBMThread11.DLL Registration-Free. (Side-by-side)
    Keep in mind that this technology needs at minimum Windows XP SP2 or Windows Server 2003.

    Big thanks goes to 'the trick' for the solution with "comInterfaceExternalProxyStub" in the manifest.

    Tutorial:
    The "Development" machine needs to register VBMThread11.DLL as usual and use the components for e.g. in a Std-EXE project.
    The source project needs to include the Side-by-side resources. (see below)
    Then on the "End user" machine you only need the VBMThread11.DLL and the .exe (Std-EXE project) on the same folder.
    It will work then without any registration.

    The source code of "VBMThread11SideBySide.res" is:

    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       <file name="VBMThread11.DLL">
          <typelib tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}" version="1.0" flags="" helpdir="" />
          <comClass clsid="{AAE10FA6-5E20-4FA7-9649-678DC3971353}" tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}" threadingModel="Apartment" progid="VBMThread11.Thread" description="" />
       </file>
       <comInterfaceExternalProxyStub
          name = "_Thread"
          iid="{71154E34-A914-4E30-A4BA-5CE94A6D9C46}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
       </comInterfaceExternalProxyStub>
       <comInterfaceExternalProxyStub
          name = "__Thread"
          iid="{403717A2-9E4E-4FEC-B77A-62DC68B9C294}"
          proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
       </comInterfaceExternalProxyStub>
       <comInterfaceExternalProxyStub
          name = "_ThreadData"
          iid="{55A8AC17-7DB5-468D-93BD-86E8B97C53A5}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
       </comInterfaceExternalProxyStub>
       <comInterfaceExternalProxyStub
          name = "_IThread"
          iid="{68F61D7E-21CD-41E6-AFEC-C3820C6743D5}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
       </comInterfaceExternalProxyStub>
       <comInterfaceExternalProxyStub
          name = "_IThreadStatusCallback"
          iid="{09256C4A-7A89-40F6-BBEE-3D5445942C4A}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
       </comInterfaceExternalProxyStub>
    </assembly>
    In the attachment I have added the same as a compiled resource.
    Attached Files Attached Files
    Last edited by Krool; Apr 29th, 2017 at 09:41 AM.

  12. #12
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    323

    Re: VB Multithread Library (Generic Multithreader)

    Dear Krool, how can i use the res file?
    i have try to find the original post about comInterfaceExternalProxyStub, but found nothing.
    can you indicate it

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    It is also possible to add more complexity in the interaction between the AsyncProcedure and SyncCallback events.
    So one would create a project class called cParams, which could just contain two properties named 'Command' and 'Value'.

    Code:
    Private Sub BackWorker_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
    Dim Params As cParams
    Set Params = New cParams
    Params.Command = "Do that and this"
    Params.Value = 150
    SyncCallback.Raise Params
    End Sub
    
    Private Sub BackWorker_SyncCallback(Argument As Variant)
    If Argument.Command = "Do that and this" Then MsgBox Argument.Value
    End Sub
    Conclusion:
    In general there seems to be no issue to create or even access classes from the project, at least for simple classes, within the AsyncProcedure event.
    Last edited by Krool; Dec 18th, 2016 at 10:34 AM.

  14. #14
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    It seems like the runtime has no issue automatically marshalling our interfaces between threads?

  15. #15
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    It seems very useful.
    Thanks for the sample project.

    I would be even better if the objects of the main thread could be used, something like SyncCallback.Marshall(SomeRecordset).MoveFirst...
    But perhaps it's too difficult to do (or am I saying nonsense?).

  16. #16
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Eduardo- View Post
    It seems very useful.
    Thanks for the sample project.

    I would be even better if the objects of the main thread could be used, something like SyncCallback.Marshall(SomeRecordset).MoveFirst...
    But perhaps it's too difficult to do (or am I saying nonsense?).
    You can marshall interfaces to the async procedure yourself if you really need to, but using the SyncCallback is way easier.
    Also hopefully the example you posted wasnt a real world usage...

    using a Recordset on the main thread from another thread - completely defeats the purpose of using another thread.
    Last edited by DEXWERX; Apr 20th, 2017 at 01:53 PM.

  17. #17
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by DEXWERX View Post
    You can marshall interfaces to the async procedure yourself if you really need to, but using the SyncCallback is way easier.
    Also hopefully the example you posted wasnt a real world usage...
    How do you do that?
    How do you send an object from the SyncCallback to be used in the async procedure (the one that executes in the new thread)?

    Quote Originally Posted by DEXWERX View Post
    using a Recordset on the main thread from another thread - completely defeats the purpose of using another thread.
    As I understand it, may be or may be not.
    If I would be doing intensive use of the recorset you are right, but if I only needed to make some consult (and the main task is another one) not, I think.

  18. #18
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Eduardo- View Post
    How do you do that?
    How do you send an object from the SyncCallback to be used in the async procedure (the one that executes in the new thread)?
    https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

    I guess I can try and put together a demo, but the Threading DLL source shows how to manually martial a "Thread" interface from the main thread onto the new thread.

    Quote Originally Posted by Eduardo- View Post
    As I understand it, may be or may be not.
    If I would be doing intensive use of the recorset you are right, but if I only needed to make some consult (and the main task is another one) not, I think.
    That's correct, just trying to be clear. MoveFirst implied you're going to use a recordset in a loop. *shrugs*

  19. #19
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Funny story... You can use COM's automatic martialling.

    Code:
    Option Explicit
    
    Private WithEvents t As Thread
    Private m_Rec As ADODB.Recordset
    
    Private Sub Form_Click()
        t.Create
    End Sub
    
    Private Sub Form_Load()
        'Create In Memory Recordset
        Set m_Rec = New ADODB.Recordset
        With m_Rec
            .Fields.Append "Name", adVarChar, 10, adFldMayBeNull
            .CursorType = adOpenKeyset
            .CursorLocation = adUseClient
            .LockType = adLockPessimistic
            .Open
            Dim Ind As Long
            For Ind = 1 To 5
                .AddNew
                .Fields(0) = "Name " & Ind
                .Update
                .MoveNext
            Next
        End With
        
        Set t = New Thread
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        If t.hThread <> 0 Then
            Cancel = True
            MsgBox "Thread is not complete."
            Exit Sub
        End If
    End Sub
    
    Private Sub t_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
        Dim a, MyRec As ADODB.Recordset
        SyncCallback.Raise a
        Set MyRec = a
        MyRec.MoveFirst
        Do Until MyRec.EOF
            'OutputDebugString MyRec.Fields(0)
            SyncCallback.Raise MyRec.Fields(0).Value
            MyRec.MoveNext
        Loop
    End Sub
    
    Private Sub t_SyncCallback(Argument As Variant)
        If VarType(Argument) = vbString Then
            MsgBox Argument
        Else
            Set Argument = m_Rec
        End If
    End Sub

  20. #20
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    Ah, that's great, then... does the Argument parameter marshall any COM object passed between the procedures?
    (I still didn't study the DLL source code)

    Another question: only one object at a time can be marshalled?

  21. #21
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Eduardo- View Post
    Ah, that's great, then... does the Argument parameter marshall any COM object passed between the procedures?
    (I still didn't study the DLL source code)

    Another question: only one object at a time can be marshalled?
    It doesn't seem like private objects. But you can automatically Marshall private objects as IDispatch (Object).
    And then latebound calls work.

    Code:
    Private Sub t_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
        Dim a, f, MyRec As ADODB.Recordset, MyForm As Object 'Form1 is private to main thread...
        SyncCallback.Raise a
        Set MyRec = a
        f = "Form"
        SyncCallback.Raise f
        Set MyForm = f
        MyForm.Caption = "Caption Set From the other thread!"
        MyRec.MoveFirst
        Do Until MyRec.EOF
            SyncCallback.Raise MyRec.Fields(0).Value & " - " '& WINAPI.GetCurrentThreadId ' API's called on other thread using a typelib.
            MyRec.MoveNext
        Loop
    End Sub
    
    Private Sub t_SyncCallback(Argument As Variant)
        If VarType(Argument) = vbString Then
            Select Case Argument
            Case "Form"
                Dim Obj As Object
                Set Obj = Me
                Set Argument = Obj
            Case Else
                MsgBox "Main Thread: " & App.ThreadID() & " " & Argument
            End Select
        Else
            Set Argument = m_Rec
        End If
    End Sub
    or an Array of Variant or Object. Seems to work.

    Code:
    Private Sub t_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
        Dim a, MyRec As ADODB.Recordset, MyForm As Object 'Form1
        SyncCallback.Raise a
        Set MyForm = a(0)
        Set MyRec = a(1)
        MyForm.Caption = "Caption Set From the other thread!"
        MyRec.MoveFirst
        Do Until MyRec.EOF
            SyncCallback.Raise MyRec.Fields(0).Value & " - " & WINAPI.GetCurrentThreadId
            MyRec.MoveNext
        Loop
    End Sub
    
    Private Sub t_SyncCallback(Argument As Variant)
        Dim Args(1) ' As Object ' Or As Variant
        Dim Obj As Object: Set Obj = Me
        
        If VarType(Argument) = vbString Then
            MsgBox "Main Thread: " & App.ThreadID() & " " & Argument
        Else
            Set Args(0) = Obj
            Set Args(1) = m_Rec
            Argument = Args
        End If
    End Sub
    Last edited by DEXWERX; Apr 20th, 2017 at 04:04 PM.

  22. #22
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    Great. That is very useful. Thanks a lot.

  23. #23
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Thanx for the project. Unfortunately, and maybe nothing you can do about it, it isn't very safe in the IDE. For example, I tried to terminate any active threads in form unload while the progress bar window was running, but it crashed. When compiled, no crash. The simple example looked like this:
    Code:
        Me.Hide
        If BackgroundWorker.hThread Then
            Do Until BackgroundWorker.Terminate = True
                Sleep 100
            Loop
        End If
        If FormWorker.hThread Then
            Do Until FormWorker.Terminate = True
                Sleep 100
            Loop
        End If
    Maybe your library can provide an optional synchronous Terminate event? Returning only when thread successfully terminated? Kinda like:
    Code:
    Public Function Terminate(Optional AsSynchronous As Boolean = False) As Boolean
    Edited: If you consider the above request, maybe consider adding a Synch option to other functions, like Suspend, etc. Doing so should negate the main thread from having to loop, if necessary, while waiting for the action to take effect
    Last edited by LaVolpe; Apr 22nd, 2017 at 04:06 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  24. #24
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Hoping you will consider the synchronous functions described previously. In any case, I'd like to say this project feels pretty good and would like to provide some positive feedback after a few preliminary tests I've done:

    Overview the way I understand it: The thread is purely a background thread. After the AsyncProcedure callback returns to the Thread class, the thread is automatically terminated. In other words, when the main thread's final SyncCallback routine exits, consider the thread dead. Final? Yep, as shown in posts above, you may have designed the AsyncProcedure to have multiple SyncCallback calls.

    Task 1: I was thinking of using multi-threading for GDI+ loaded GIFs and other animation. The idea was to pass the thread a GDI+ image handle and frame number. The thread would prepare the frame, render to a DC with any special rendering options. The main thread would draw the frame when either the thread finished or the previous frame's duration occurred, whichever occurs latest. Afterwards, another thread created and next frame is processed. This appears to work pretty well. Main thread is not tied up during the processing of the frame. If multiple images are being animated; this is noticeable. Very good.

    Task 2: Have GDI+ load an image within the background thread and return the image handle to the main thread when done. For very large images, the main thread is not tied up. Again, very good.

    The key point here, for those that mess with GDI+, is that it appears the image handle can be passed between threads without crashing. I wasn't positive about that. I've tested creating the GDI+ image in the background thread and processing it in the main thread and vice versa. In either scenario the image handle was created and processed in different threads. Of course, some care needs to be taken. Accessing the image handle simultaneously in both threads would likely end in unexpected results, at best, crashes at worst; especially with multi-image formats like GIF/TIFF. More testing needed.
    Last edited by LaVolpe; Apr 22nd, 2017 at 07:05 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  25. #25

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by LaVolpe View Post
    Hoping you will consider the synchronous functions described previously. In any case, I'd like to say this project feels pretty good and would like to provide some positive feedback after a few preliminary tests I've done:

    Overview the way I understand it: The thread is purely a background thread. After the AsyncProcedure callback returns to the Thread class, the thread is automatically terminated. In other words, when the main thread's final SyncCallback routine exits, consider the thread dead. Final? Yep, as shown in posts above, you may have designed the AsyncProcedure to have multiple SyncCallback calls.
    Thanks for testing. It seems like a 1.1 version is overdue.
    I would also like to add a 'Argument2' in the SyncCallback to enable more flexibility out of the box without extra tricks, like array etc.

    For the sync Terminate function. So like a "Public Function Terminate(Optional ByVal Wait As Boolean)"
    When passing True at call the function would return only when the thread is finally terminated?

    About your understanding overview. Yes, correct. If the AsyncProcedure returns the task is finished and thread is terminated automatically.
    The SyncCallback can be called multiple times or none at all. That's not a condition to have it called at least once.
    Last edited by Krool; Apr 23rd, 2017 at 04:24 AM.

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    I would also like to add a 'Argument2' in the SyncCallback to enable more flexibility out of the box without extra tricks, like array etc.
    Still may not be enough for many calls. In my GDI+ example, I may want to pass an image handle, frame number, color attributes handle and more for processing within the background thread. Dex showed how an array can be assigned to the variant argument for passing multiple values & I feel it's a good workaround. But at least two parameters would be better, something as you described in your post #13. This way SyncCallback can be better written by the user by testing the "command" parameter passed from AsyncProcedure.

    Regarding raised events. Within VB, these are blocked when a modal form/window (i.e., MsgBox) is displayed within the IDE. An implementation vs withevents would solve that issue. Is this a real concern? Yes, possibly. In my GDI+ example, if the thread creates the image handle then calls the SyncCallback to pass the handle and the event is blocked, the main thread doesn't know about the handle and cannot free/release it. Of course, a workaround would be to require the SyncCallback to pass a flag within the arguments to determine if the call was received from AsyncProcedure. However, instead of testing every call, an implementation would be a better solution. Example of event blocking, the debug statement is not executed...
    Code:
    Private Sub Command1_Click()
       BackgroundWorker.Create
       MsgBox "Block Events"
    End Sub
    
    Private Sub BackgroundWorker_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
        SyncCallback.Raise 0
    End Sub
    
    Private Sub BackgroundWorker_SyncCallback(Argument As Variant)
       ' ^^^ This is blocked when modal window exists
       Debug.Print "syncCallback received'
    End Sub
    When passing True at call the function would return only when the thread is finally terminated?
    Yes, that's the idea & similar for Suspend
    Last edited by LaVolpe; Apr 23rd, 2017 at 10:29 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by LaVolpe View Post
    Regarding raised events. Within VB, these are blocked when a modal form/window (i.e., MsgBox) is displayed within the IDE. An implementation vs withevents would solve that issue. Is this a real concern? Yes, possibly. In my GDI+ example, if the thread creates the image handle then calls the SyncCallback to pass the handle and the event is blocked, the main thread doesn't know about the handle and cannot free/release it. Of course, a workaround would be to require the SyncCallback to pass a flag within the arguments to determine if the call was received from AsyncProcedure. However, instead of testing every call, an implementation would be a better solution. Example of event blocking, the debug statement is not executed...
    Code:
    Private Sub Command1_Click()
       BackgroundWorker.Create
       MsgBox "Block Events"
    End Sub
    
    Private Sub BackgroundWorker_AsyncProcedure(ByVal SyncCallback As VBMThread10.IThreadSyncCallback)
        SyncCallback.Raise 0
    End Sub
    
    Private Sub BackgroundWorker_SyncCallback(Argument As Variant)
       ' ^^^ This is blocked when modal window exists
       Debug.Print "syncCallback received'
    End Sub
    I could imagine the following solution. To have either way.

    Include in the Thread class a 'CustomIThreadSyncCallback' property. When this is Nothing fire normal event, else use the interface.

    So in Form you include IThreadSyncCallback and you then would do a "Set Thread.CustomIThreadSyncCallback = Me", where 'Me' is the Form.

  28. #28
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    That may be a workaround. However, if you are going to update this library, suggest using an Interface instead of raising events. I believe that is a better and cleaner overall solution. The form/uc/class that is creating the thread can pass itself to the thread's Create method and the Terminate method can release the reference. The raiseevent calls would be replaced by calling the implementation instead.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  29. #29

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    But the AsyncProcedure can stay as an event?
    So in the Create method there would be an additional non-optional IThreadSyncCallback parameter by which 'Me' will be normally passed.

    Or else a second interface is needed for the Async part.

  30. #30
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Krool, I don't have the deep understanding of multi-threading that you do. Is there reason why you need to RaiseEvent vs. an Implementation? The idea I was suggesting is something like this. It is rough, not polished:
    Code:
    ' new Interface to be used by customers. Let's say it's named: IThread
    Public Sub AsyncProcedure(ByVal SyncCallback As IThreadSyncCallback): End Sub
    Public Sub SyncCallback(ByRef Argument As Variant): End Sub
    
     ' the Thread.Cls
    add this: Private m_Consumer As IThread
    change Create to: Public Function Create(Owner As IThread) As Boolean
       Set m_Consumer = Owner ' validate that Nothing was not passed
    
     ' then instead of raising the two events, this:
             m_Consumer.SyncCallback Argument
    and   m_Consumer.AsyncProcedure SyncCallback
    
    add this in the Terminate event:
       Set m_Consumer = Nothing
    The caller would use: Implements IThread
    and then initiate with: BackgroundWorker.Create Me

    Edited: Many of the changes you make may break binary compatibility, unless you create new function names, i.e., CreateEx instead of modifying the Create function signature.
    Last edited by LaVolpe; Apr 23rd, 2017 at 11:01 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  31. #31

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Good idea. Thought also that new interface is needed.
    But ofcourse the new 'IThread' can provide both "events".
    Will check this soon.

    Also I might include an optional 'ByVal CustData As Long' in the Create method which will be passed along AsyncProcedure.

  32. #32
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Also I might include an optional 'ByVal CustData As Long' in the Create method which will be passed along AsyncProcedure.
    Good idea. This way if the AsyncProcedure has no other reason to call SyncCallback, it doesn't need to and the task can be completely handled in the background thread as long as the user has a way to confirm that the task succeeded (exit code or some other method). Or Maybe the AsyncProcedure calls SyncCallback to pass success or failure?
    Last edited by LaVolpe; Apr 23rd, 2017 at 11:12 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  33. #33

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by LaVolpe View Post
    Edited: Many of the changes you make may break binary compatibility, unless you create new function names, i.e., CreateEx instead of modifying the Create function signature.
    I will need to break binary compatibility anyhow as I will remove some events, thus 1.1 version.
    Ofcourse then I need to create a new manifest resource. But it's cleaner that way instead of bloating everything up.

  34. #34
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    One more, minor suggestion:
    Change AsyncProcedure name to BkgThreadProcedure
    Change SyncCallback name to MainThreadProcedure

    Or some other names that may be more intuitive/descriptive of what is occurring in the event. It may be more helpful to users to better understand which event belongs to the multi-thread and which belongs to the main thread. Just a thought.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  35. #35
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    With the events interface it is possible to add several new threads code to the same form (or same instance of a class module), but with the version using implements, for also enabling that possibility, it would have to have an additional parameter to identify the thread, I think.

    Edit: it can be the thread's name, so the code to create the thread, intead of:

    Code:
    BackgroundWorker.Create
    it could be:

    Code:
    CreateThread "BackgroundWorker"
    Last edited by Eduardo-; Apr 23rd, 2017 at 12:00 PM.

  36. #36
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by Eduardo- View Post
    With the events interface it is possible to add several new threads code to the same form (or same instance of a class module), but with the version using implements, for also enabling that possibility, it would have to have an additional parameter to identify the thread, I think.
    Good point. There are at least 2 ways of handling that

    1. As you suggest, Krool could add a Key parameter to the Create event and that value passed with each implemented method. The user can Select Case / If:Else on that key. Many solutions use a key or user param to identify which instance is being used.

    2. Create a class for each type of background thread and have the class Implement the interface, then pass the class instance instead of the form instance.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  37. #37

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,374

    Re: VB Multithread Library (Generic Multithreader)

    I also have the idea of bringing up a 'ThreadCancelBoolean' class which has a Value Boolean property (default property) that is passed along 'AsyncProcedure'.
    Kind of "AsyncProcedure(SyncCallback As IThreadSyncCallback, Cancel As ThreadCancelBoolean)
    In the Thread class there would be a Cancel method to make a 'soft terminate'.
    So in the AsyncProcedure there could be an "If Cancel = True" be included by the coder to bring the AsyncProcedure faster to it's end.

    Concerning the description. I do find Async.. and Sync.. already as self-explained? Or?

  38. #38
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB Multithread Library (Generic Multithreader)

    Concerning the description. I do find Async.. and Sync.. already as self-explained? Or?
    Maybe I am too dense I didn't pick that up right away. Your control, your rules. Something we can all live by.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  39. #39
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    If passing a string is not much overhead, I suggest to identify each threads with a name.

    Code:
    Implements IThreads
    
    Private Sub Form_Load()
        CreateThread "BackgroundWorker1"
        CreateThread "BackgroundWorker2"
    End Sub
    
    Private Sub IThread_AsyncProcedure(TheadName As String, asSyncCallback As IThreadSyncCallback, Cancel As ThreadCancelBoolean)
    
    End Sub
    
    Private Sub IThread_SyncCallback(TheadName As String, Argument1 As Variant, Argument2 As Variant)
    
    End Sub
    And about the names, I vote for Lavolpe's suggestion of BkgThreadProcedure and MainThreadProcedure. I think they are more intuitive.
    Last edited by Eduardo-; Apr 23rd, 2017 at 12:17 PM.

  40. #40
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: VB Multithread Library (Generic Multithreader)

    Quote Originally Posted by LaVolpe View Post
    Your control, your rules. Something we can all live by.
    Of course.

Page 1 of 3 123 LastLast

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