Results 1 to 10 of 10

Thread: Thread Execute Plug-in

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Arrow Thread Execute Plug-in

    Hello all.

    I succeeded in making something awesome: A thread execute plug-in!.
    Basically it executes the given sub on a separate thread using delegates.
    I also made a "Delegate Execute" plug-in to invoke a sub.

    Thread Execute code Code:
    1. #Region "Thread Execute"
    2.     Public Delegate Sub DSparam0()
    3.     Public Delegate Sub DSparam1(ByVal Param1 As Object)
    4.     Public Delegate Sub DSparam2(ByVal Param1 As Object, ByVal Param2 As Object)
    5.     Public Delegate Sub DSparam3(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object)
    6.     Public Delegate Sub DSparam4(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object, ByVal Param4 As Object)
    7.     Public Delegate Sub DSparam5(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object, ByVal Param4 As Object, ByVal Param5 As Object)
    8.     Private TData As New List(Of Object)
    9.     Public Sub ThreadExecute(ByVal Subname As DSparam0)
    10.         TExec(Subname, Nothing)
    11.     End Sub
    12.     Public Sub ThreadExecute(ByVal Subname As DSparam1, ByVal ParamArray Parameters() As Object)
    13.         TExec(Subname, Parameters)
    14.     End Sub
    15.     Public Sub ThreadExecute(ByVal Subname As DSparam2, ByVal ParamArray Parameters() As Object)
    16.         TExec(Subname, Parameters)
    17.     End Sub
    18.     Public Sub ThreadExecute(ByVal Subname As DSparam3, ByVal ParamArray Parameters() As Object)
    19.         TExec(Subname, Parameters)
    20.     End Sub
    21.     Public Sub ThreadExecute(ByVal Subname As DSparam4, ByVal ParamArray Parameters() As Object)
    22.         TExec(Subname, Parameters)
    23.     End Sub
    24.     Private Sub TExec(ByVal Deleg As Object, ByVal Parameters() As Object)
    25.         TData.Clear()
    26.         TData.Add(False)
    27.         TData.Add(Deleg)
    28.         If IsArray(Parameters) Then TData.AddRange(Parameters)
    29.         Dim t As New Threading.Thread(AddressOf EXECTHREAD)
    30.         t.IsBackground = True
    31.         t.Start()
    32.         Do While TData(0) = False
    33.             Threading.Thread.Sleep(100)
    34.         Loop
    35.     End Sub
    36.     Private Sub EXECTHREAD()
    37.         '0 = started
    38.         '1 = delegate
    39.         '2 - inf = parameters
    40.         TData(0) = True
    41.         If TData(1).GetType.Name = "DSparam0" Then CType(TData(1), DSparam0)()
    42.         If TData(1).GetType.Name = "DSparam1" Then CType(TData(1), DSparam1)(TData(2))
    43.         If TData(1).GetType.Name = "DSparam2" Then CType(TData(1), DSparam2)(TData(2), TData(3))
    44.         If TData(1).GetType.Name = "DSparam3" Then CType(TData(1), DSparam3)(TData(2), TData(3), TData(4))
    45.         If TData(1).GetType.Name = "DSparam4" Then CType(TData(1), DSparam4)(TData(2), TData(3), TData(4), TData(5))
    46.     End Sub
    47. #End Region

    Now I want to decrease the coding size some more, and therefore my question:
    How can I specify multiple types for a byval parameter in a sub?
    At this point it overloads the other subs to get the desired amount of needed parameters. (max is 5 atm). I want to do this without overloading.

    As example the following two subs:

    Code:
        Public Sub ThreadExecute(ByVal Subname As DSparam1, ByVal ParamArray Parameters() As Object)
            TExec(Subname, Parameters)
        End Sub
        Public Sub ThreadExecute(ByVal Subname As DSparam2, ByVal ParamArray Parameters() As Object)
            TExec(Subname, Parameters)
        End Sub
    I want to change that to, for example, this:

    Code:
        Public Sub ThreadExecute(ByVal Subname As [DSparam1 or DSparam2], ByVal ParamArray Parameters() As Object)
            TExec(Subname, Parameters)
        End Sub
    How can I do that?

  2. #2
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Thread Execute Plug-in

    If you're passing an Object(), just put the subname in that array too so you only have one parameter to pass.

    Code:
        Public Sub ThreadExecute(ByVal ParamArray Parameters() As Object)
            TExec(Subname, Parameters)
        End Sub
    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Thread Execute Plug-in

    That is not going to work, because I need to pass an address to a sub.
    For the iinformation, the ThreadExecute sub is used the following way:

    Code:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            ThreadExecute(AddressOf looptest, 20000)
        End Sub
        Private Sub looptest(ByVal StartVal As Integer)
            Dim i As Integer = StartVal
            Do
                i += 1
                Debug.WriteLine("Current value is: " & i)
            Loop
        End Sub
    If I reference to a different sub with 2 parameters, it uses the delegate:
    Public Delegate Sub DSparam2(ByVal Param1 As Object, ByVal Param2 As Object)
    And with 3 parameters:
    Public Delegate Sub DSparam3(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object)

    I can't use an object for byval type, because it then gives the error:
    "'AddressOf' expression cannot be converted to 'Object' because 'Object' is not a delegate type."

    So, I can't use an object and have to use a delegate type of the list.
    (Question is getting more and more trickier...)

  4. #4
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Thread Execute Plug-in

    I did something like the following, and it worked just fine:

    vb Code:
    1. Dim obj As Object()
    2.         obj = New Object() {New Hello(AddressOf updateTB), "text", 1}
    3.  
    4.         Dim d As Hello = obj(0)
    5.         Me.Invoke(d, New Object() {"it worked!"})
    6.  
    7.         Dim s As String = CStr(obj(1))
    8.         MessageBox.Show(s)

    You can store the delegate object an object array after it has it's addressof info set. then invoke that method on the appropriate form.

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Thread Execute Plug-in

    Uh lol that is not the intention of my coding. xD

    No "invoke" may be used, because then it is not running on a thread but on a form.

    The big question is:

    - How can I specify a list of types to use in a byval sub, without using the object type (can't use it as a delegate) and without overloading?

    So for example:
    Code:
        Private Sub Test(ByVal A As (integer or string))
            If A.GetType.Name = "string" Then
                'process string: A
            ElseIf A.GetType.Name = "integer" Then
                'process integer: A
            End If
        End Sub
    I want to use this sub like this: (with different parameters)
    Code:
    Test(AddressOf TheSub, Parameters)
    The sub "TheSub" can have different parameter counts, so therfore I need to use multiple different delegates with different parameter counts.

    No codes like this:
    //cant set an object to addressof because it isnt a delegate type
    Code:
        Private Sub Test(ByVal A As Object)
            If A.GetType.Name = "string" Then
                'process string: A
            ElseIf A.GetType.Name = "integer" Then
                'process integer: A
            End If
        End Sub
    //this is overloading and will result in, eventually, 20 - 30 subs which is just too much
    Code:
        Private Sub Test(ByVal A As Integer)
            'process integer: A
        End Sub
        Private Sub Test(ByVal A As String)
            'process string: A
        End Sub
    What do I have to do, without overloading as I do now, to use multiple types?
    Last edited by bergerkiller; Jul 8th, 2010 at 02:09 PM.

  6. #6
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Thread Execute Plug-in

    What do I have to do, without overloading as I do now, to use multiple types?
    I don't think you can... Even if you could, the type passed (which would encompass all types) would still have to be cast to the specfic type to be used. That's what Object is for, but in your case won't work, so overloading is your best bet.

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  7. #7
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Thread Execute Plug-in

    To be able to pass a single parameters with mulitple possible type values, you either pass some sort of generic(object) collection(array/arraylist) or you create a class with those desired properties with corresponding types and set/get them as needed.

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Thread Execute Plug-in

    Both good replies, thank you

    The overloading works, but I would indeed need an overlapping type.

    Then that changes the question a little, how can I pass a sub name without using a delegate?

  9. #9
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Thread Execute Plug-in

    If you just want to pass the name of the sub routine, then do that. Then in whatever function you pass it to, you could compare the sub name provided and then execute that given sub routine.

    For Example:

    Code:
    
    Public Sub ExecuteSubRoutineByName(SR as String)
    
    If string.equals(SR,"LoadStrings",StringComparison.CurrentCultureIgnoreCase) then
    
    LoadStrings()
    
    End If
    
    
    End Sub
    That's the only way I could think of doing it by name. Else you would have to use the Delegate (addressof function). If you delcare a delegate in your class that you're passing the addressof to, and then set it equal to that address of passed to your function, it would work just fine.

    Code:
    Public Class DelTest
    
    Public Delegate Sub DoSomething(str as string)
    Public Delegate Sub DoSomethingInt(i as integer)
    
    Public Sub New(del as Object, param as string)
    
    try
    Dim d as DoSomething = del
    d.Invoke(param)
    catch ex as exception
    ' wrong new sub to call with that delegate
    end try
    
    End Sub
    End Class
    But you can still see that you'll have to try and match up the delegate to the certain signature of the function that you pass to the constructor.

    Justin
    Last edited by MonkOFox; Jul 9th, 2010 at 12:00 PM.
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Thread Execute Plug-in

    Thanks that helped a little in my understanding of delegates

    Also, I read some page explaining the use of address pointers pointing towards memory to get the sub name. One thing is clear, subs and functions can't be looked up using code. They are just "there" and you can't loop through them like an array.

    But, my class still is freaking awesome! I can now easily "thread" a sub without the nasty repetitive lines.
    For example; this is a delegated sub: before and after:

    Before:
    Code:
        Delegate Sub myProgressbarAdapter(ByVal percent As Integer)
        Private Sub ProgressbarAdapter(ByVal percent As Integer)
            If Me.InvokeRequired Then
                Dim d As New myProgressbarAdapter(AddressOf ProgressbarAdapter)
                Me.Invoke(d, percent)
            Else
                Progressbar1.Value = percent
            End If
        End Sub
    After:
    Code:
        Private Sub ProgressbarAdapter(ByVal percent As Integer)
            If Me.InvokeRequired Then
                DelegateExecute(Me, AddressOf ProgressbarAdapter, percent)
            Else
                Progressbar1.Value = percent
            End If
        End Sub
    It really enhanced the coding

    The following problems still seem unexplained to me:
    - Why can't you have two optional byval parameters?
    - Why can't you give a delegate a paramarray?
    Last edited by bergerkiller; Jul 9th, 2010 at 01:55 PM.

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