|
-
Jul 8th, 2010, 11:56 AM
#1
Thread Starter
Fanatic Member
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:
#Region "Thread Execute"
Public Delegate Sub DSparam0()
Public Delegate Sub DSparam1(ByVal Param1 As Object)
Public Delegate Sub DSparam2(ByVal Param1 As Object, ByVal Param2 As Object)
Public Delegate Sub DSparam3(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object)
Public Delegate Sub DSparam4(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object, ByVal Param4 As Object)
Public Delegate Sub DSparam5(ByVal Param1 As Object, ByVal Param2 As Object, ByVal Param3 As Object, ByVal Param4 As Object, ByVal Param5 As Object)
Private TData As New List(Of Object)
Public Sub ThreadExecute(ByVal Subname As DSparam0)
TExec(Subname, Nothing)
End Sub
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
Public Sub ThreadExecute(ByVal Subname As DSparam3, ByVal ParamArray Parameters() As Object)
TExec(Subname, Parameters)
End Sub
Public Sub ThreadExecute(ByVal Subname As DSparam4, ByVal ParamArray Parameters() As Object)
TExec(Subname, Parameters)
End Sub
Private Sub TExec(ByVal Deleg As Object, ByVal Parameters() As Object)
TData.Clear()
TData.Add(False)
TData.Add(Deleg)
If IsArray(Parameters) Then TData.AddRange(Parameters)
Dim t As New Threading.Thread(AddressOf EXECTHREAD)
t.IsBackground = True
t.Start()
Do While TData(0) = False
Threading.Thread.Sleep(100)
Loop
End Sub
Private Sub EXECTHREAD()
'0 = started
'1 = delegate
'2 - inf = parameters
TData(0) = True
If TData(1).GetType.Name = "DSparam0" Then CType(TData(1), DSparam0)()
If TData(1).GetType.Name = "DSparam1" Then CType(TData(1), DSparam1)(TData(2))
If TData(1).GetType.Name = "DSparam2" Then CType(TData(1), DSparam2)(TData(2), TData(3))
If TData(1).GetType.Name = "DSparam3" Then CType(TData(1), DSparam3)(TData(2), TData(3), TData(4))
If TData(1).GetType.Name = "DSparam4" Then CType(TData(1), DSparam4)(TData(2), TData(3), TData(4), TData(5))
End Sub
#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?
-
Jul 8th, 2010, 12:21 PM
#2
Frenzied Member
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
-
Jul 8th, 2010, 12:28 PM
#3
Thread Starter
Fanatic Member
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... )
-
Jul 8th, 2010, 12:39 PM
#4
Frenzied Member
Re: Thread Execute Plug-in
I did something like the following, and it worked just fine:
vb Code:
Dim obj As Object()
obj = New Object() {New Hello(AddressOf updateTB), "text", 1}
Dim d As Hello = obj(0)
Me.Invoke(d, New Object() {"it worked!"})
Dim s As String = CStr(obj(1))
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
-
Jul 8th, 2010, 01:17 PM
#5
Thread Starter
Fanatic Member
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.
-
Jul 8th, 2010, 02:26 PM
#6
Frenzied Member
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
-
Jul 8th, 2010, 02:28 PM
#7
Frenzied Member
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
-
Jul 8th, 2010, 03:42 PM
#8
Thread Starter
Fanatic Member
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?
-
Jul 9th, 2010, 11:51 AM
#9
Frenzied Member
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.
-
Jul 9th, 2010, 01:51 PM
#10
Thread Starter
Fanatic Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|