views:

65

answers:

5

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
A: 

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.

ho1
Yes, it worked with one parameter using ParameterizedThreadStart. But I want to use the same solution for one or two or more paramenters
elcool
A: 

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)
Konrad Rudolph
I read about this lambdas, but I'm using VS 2008 with VB8 I believe. Don't have VB10
elcool
+1  A: 

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 ;)

Dario
Nice answer, but I don't have VB10. *just edited my question
elcool
@elcool: I don't think this requires .Net 4.0 or VS 2010. This looks like .Net 3.5 to me.
dboarman
it gives me a Compile error: `Expression Expected.` on Sub
elcool
@dboarman: It is VB2010 ... The 3.5-Version is limited to `Function(...)`-Lambdas but unable to handle `Sub`s
Dario
@Dario: ah, the `Sub()` -- missed that part. I'm still doing VB/C# 3.5 at work and only C# 4.0 at home.
dboarman
A: 

Something like this (I'm not a VB programmer)

Public Class MyParameters
    public property Name As String
    public property Number As Integer
End Class



Thread newThread = 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)

}
jgauffin
+1  A: 

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)
Jay
DynamicInvoke ... goodbye type safety. A valid answer nontheless.
Dario