Passing a method as an argument for another method:
Public Sub NewThread(Method As Action)
Me.TaskThread = New Thread(New ThreadStart(Method))
End Sub
Results for error:
Error BC32008: "Delegate 'ThreadStart' requires an 'AddressOf' expression or lambda expression as the only argument to its constructor."
And
Public Sub NewThread(Method As Action)
Me.TaskThread = New Thread(New ThreadStart(AddressOf Method))
End Sub
Results for error:
Error BC30577: "'AddressOf' operand must be the name of a method (without parentheses)."
What went wrong and how to fix it?
The constructor of Thread expects a delegate. Traditionally, if you have a method, say, MyMethod:
Private Sub MyMethod()
' Do stuff.
End Sub
You'd call the constructor as follows:
Me.TaskThread = New Thread(AddressOf MyMethod)
Notice that AddressOf is to be followed by the name of the method (without parentheses). But since you have the method as a delegate parameter (of type Action), you need to pass as a lambda expression like this:
Me.TaskThread = New Thread(Sub() Method())
What I've got is something like this:
Private Sub GiantLegacySub()
... lots of variables and legacy code...
Dim somethingNew = New Func(of String, Boolean)(
Function(stringy as String) As Boolean
... new code that uses the legacy variables ...
End Function)
Dim t = New Thread(AddressOf somethingNew)
End Sub
I am getting an error indicating that somethingNew is being seen as variable name and not a method name and is thus unacceptable by AddressOf. ( I know that somethingNew is a variable, just one that happens to contain a pointer to a method).
Is there a way to do this? I need to leave it inside of GiantLegacySub because of the shear volume of variables in its scope.
Based on Craig's guidance, this was the answer:
Private Sub GiantLegacySub()
... lots of variables and legacy code...
Dim somethingNew = Sub(stringy as String)
... new code that uses the legacy variables ...
End Sub
Dim t = New Thread(somethingNew)
t.Start(someStringForStringy)
End Sub
Public Class Class1
Dim thread As New System.Threading.Thread(AddressOf AMethod)
thread.Start()
Public Sub AMethod()
Console.writeline("Thread start")
End Sub
End Class
The "thread.Start()" is the problematic line, according to vb.
Declaring the thread in a sub gives an overload error, whatever that means.
If you didn't understand what #Plutonix meant by "executable code floating around" (I love that phrase) here is an example:
Public Class Class1
Dim thread As New System.Threading.Thread(AddressOf AMethod)
Public Sub StartingThread()
thread.Start()
End Sub
Public Sub AMethod()
Console.WriteLine("Thread start")
End Sub
End Class
See, the executable code thread.Start() is now inside a method. I, myself, am steering clear of threading until I know much more about it.
In VB.NET, what is the syntax to start a new thread using a parameterless Action?
"what is the syntax to start a new thread using a parameterless Action"
Here are two examples:
Example 1:
Private Sub MyAction()
[... Code goes here]
End Sub
Public Sub Test()
Dim t As New Thread(AddressOf Me.MyAction)
t.Start()
End Sub
Example 2:
Dim t As New Thread(Sub() [... Code goes here])
t.Start()
Kind of years too late but...use ThreadStart
Private _calculateThread As Thread
Private Sub CreateAndStartThread(ByVal threadDelegate As ThreadStart)
_calculateThread = New Thread(threadDelegate)
_calculateThread.Start()
End Sub
and somewhere else in your code
CreateAndStartThread(New ThreadStart(AddressOf Calculate))
Private Sub Calculate()
'... do your thread actions
end Sub
I'm looking to pass two or more parameters to a thread in VB 2008.
The following method (modified) works fine without parameters, and my status bar gets updated very cool-y.
But I can't seem to make it work with one, two or more parameters.
This is the pseudo code of what I'm thinking should happen when the button is pressed:
Private Sub Btn_Click()
Dim evaluator As New Thread(AddressOf Me.testthread(goodList, 1))
evaluator.Start()
Exit Sub
This is the testthread method:
Private Sub testthread(ByRef goodList As List(Of OneItem), ByVal coolvalue As Integer)
StatusProgressBar.Maximum = 100000
While (coolvalue < 100000)
coolvalue = coolvalue + 1
StatusProgressBar.Value = coolvalue
lblPercent.Text = coolvalue & "%"
Me.StatusProgressBar.Refresh()
End While
End Sub
First of all: AddressOf just gets the delegate to a function - you cannot specify anything else (i.e. capture any variables).
Now, you can start up a thread in two possible ways.
Pass an Action in the constructor and just Start() the thread.
Pass a ParameterizedThreadStart and forward one extra object argument to the method pointed to when calling .Start(parameter)
I consider the latter option an anachronism from pre-generic, pre-lambda times - which have ended at the latest with VB10.
You could use that crude method and create a list or structure which you pass to your threading code as this single object parameter, but since we now have closures, you can just create the thread on an anonymous Sub that knows all necessary variables by itself (which is work performed for you by the compiler).
Soo ...
Dim Evaluator = New Thread(Sub() Me.TestThread(goodList, 1))
It's really just that ;)
Something like this (I'm not a VB programmer)
Public Class MyParameters
public Name As String
public Number As Integer
End Class
newThread as thread = new Thread( AddressOf DoWork)
Dim parameters As New MyParameters
parameters.Name = "Arne"
newThread.Start(parameters);
public shared sub DoWork(byval data as object)
{
dim parameters = CType(data, Parameters)
}
Dim evaluator As New Thread(Sub() Me.testthread(goodList, 1))
With evaluator
.IsBackground = True ' not necessary...
.Start()
End With
Well, the straightforward method is to create an appropriate class/structure which holds all your parameter values and pass that to the thread.
Another solution in VB10 is to use the fact that lambdas create a closure, which basically means the compiler doing the above automatically for you:
Dim evaluator As New Thread(Sub()
testthread(goodList, 1)
End Sub)
In addition to what Dario stated about the Delegates you could execute a delegate with several parameters:
Predefine your delegate:
Private Delegate Sub TestThreadDelegate(ByRef goodList As List(Of String), ByVal coolvalue As Integer)
Get a handle to the delegate, create parameters in an array, DynamicInvoke on the Delegate:
Dim tester As TestThreadDelegate = AddressOf Me.testthread
Dim params(1) As Object
params(0) = New List(Of String)
params(1) = 0
tester.DynamicInvoke(params)
Just create a class or structure that has two members, one List(Of OneItem) and the other Integer and send in an instance of that class.
Edit: Sorry, missed that you had problems with one parameter as well. Just look at Thread Constructor (ParameterizedThreadStart) and that page includes a simple sample.
Pass multiple parameter for VB.NET 3.5
Public Class MyWork
Public Structure thread_Data
Dim TCPIPAddr As String
Dim TCPIPPort As Integer
End Structure
Dim STthread_Data As thread_Data
STthread_Data.TCPIPAddr = "192.168.2.2"
STthread_Data.TCPIPPort = 80
Dim multiThread As Thread = New Thread(AddressOf testthread)
multiThread.SetApartmentState(ApartmentState.MTA)
multiThread.Start(STthread_Data)
Private Function testthread(ByVal STthread_Data As thread_Data)
Dim IPaddr as string = STthread_Data.TCPIPAddr
Dim IPport as integer = STthread_Data.TCPIPPort
'Your work'
End Function
End Class
I think this will help you...
Creating Threads and Passing Data at Start Time!
Imports System.Threading
' The ThreadWithState class contains the information needed for
' a task, and the method that executes the task.
Public Class ThreadWithState
' State information used in the task.
Private boilerplate As String
Private value As Integer
' The constructor obtains the state information.
Public Sub New(text As String, number As Integer)
boilerplate = text
value = number
End Sub
' The thread procedure performs the task, such as formatting
' and printing a document.
Public Sub ThreadProc()
Console.WriteLine(boilerplate, value)
End Sub
End Class
' Entry point for the example.
'
Public Class Example
Public Shared Sub Main()
' Supply the state information required by the task.
Dim tws As New ThreadWithState( _
"This report displays the number {0}.", 42)
' Create a thread to execute the task, and then
' start the thread.
Dim t As New Thread(New ThreadStart(AddressOf tws.ThreadProc))
t.Start()
Console.WriteLine("Main thread does some work, then waits.")
t.Join()
Console.WriteLine( _
"Independent task has completed main thread ends.")
End Sub
End Class
' The example displays the following output:
' Main thread does some work, then waits.
' This report displays the number 42.
' Independent task has completed; main thread ends.
With VB 14, you can do the following with Tuples:
Shared Sub _runner(data as (goodList As List(Of OneItem), coolvalue As Integer))
Console.WriteLine($"goodList: {data.goodList}")
Console.WriteLine($"coolvalue: {data.coolvalue}")
' do stuff...
End Sub
Dim thr As New Thread(AddressOf _runner)
thr.Start((myGoodList, cval))