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.
Related
Form1.vb
Imports System.Threading
Public Class Form1
Dim demoThread As Thread
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Start As New Class1
Me.demoThread = New Thread( _
New ThreadStart(AddressOf Start.ThreadProcSafe))
Me.demoThread.Start()
End Sub
Delegate Sub SetTextCallback([text] As String)
Public Sub SetText(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.textBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {[text]})
Else
Me.textBox1.Text = [text]
End If
End Sub
End Class
Class1.vb
Public Class Class1
Public Sub ThreadProcSafe()
Form1.SetText("This text was set safely.")
End Sub
End Class
Can someone tell me why this doesn't update the textbox?
It works when ThreadProcSafe is called when its inside Form1(and is still started by a thread) but when it's moved outside of the class into another, no warnings or errors but doesn't update.
The reason is that you are referring to the default instance in your second code snippet. Default instances are thread-specific so that second code snippet will create a new instance of the Form1 type rather then use the existing instance. Your Class1 needs a reference to the original instance of Form1.
If that's not practical then the solution is to not do the delegation in the form but rather do it in the class accessing the form, using the SynchronizationContext class.
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 have this code in my Parser and I want to pass text to Form1 so I can update some Labels or whatever.
(My structure is as follows: Form1 -> Engine -> Parser)
Sometimes I need to pass 2 strings, sometimes more.
Public Class Parser
Public Event NewInfo(<[ParamArray]()> Byval strArray() as String)
Public Sub SomeParser(ByVal m As Match)
Dim strArray() As String = {"Word1", "Word2"}
RaiseEvent NewInfo(strArray)
End Sub
End Class
Then I have this another class. I pass the Array to Engine and after that, to Form1, finally:
Public Class Engine
Private parent as Form1
Private WithEvents Parser As New Parser
Private Sub New(ByRef parent as Form1)
Me.parent = parent
EndSub
Private Sub ChangeLabel(ByVal str() As String) Handles Parser.NewInfo
parent.UpdateTextLabel(str)
End Sub
And then I have this in Form1:
Public Class Form1
Private WithEvents Engine as New Engine(Me)
Public Delegate Sub UpdateTextLabelDelegate(<[ParamArray]()> ByVal text() As String)
Public Sub UpdateTextLabel(ByVal ParamArray str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), str())
Else
(Do stuff here)
End Sub
End Class
The code stops at Me.invoke(New UpdateTextLabelDelegate).... -line.
Exception is something like: System.Reflection.TargetParameterCountException
So it means something like wrong amount of parameters.. How to do this properly?
I would be very pleased if someone could explain and if I could understand how to do this.
I don't think you need <[ParamArray]()> in your code since it's already an array that you are passing:
Public Delegate Sub UpdateTextLabelDelegate(ByVal text() As String)
And as far as passing the data through the invoke, don't use str(), just str
Public Sub UpdateTextLabel(ByVal str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), str)
Else
'(Do stuff here)
End If
End Sub
Finally managed to solve this problem. It wasn't that difficult but my mistake was something inside my own head.
I made no changes to Parser.vb so the above code is Ok.
Also, no changes to Engine.vb.
Changes to Form1.vb are here:
Public Class Form1
Private WithEvents Engine as New Engine(Me)
Public Delegate Sub UpdateTextLabelDelegate(<[ParamArray]()> ByVal text() As String)
Public Sub UpdateTextLabel(ByVal str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), New Object() {str})
Else
'(Do stuff here)
End Sub
End Class
So, all I did was to insert New Object() {args} to the invoke line and removed ParamArray from the Public Sub UpdateTextLabel -line..
But thanks for Kicking my head so I had the reason to go forward! :)
I want to make the function "createFolder" faster (or at least not blocking my main thread), by adding a new callback to my threadpool.
I marked the main function with the STAThread() and the exception tells me to mark my main function with the STAThread().
I'm open to any tips!
You have placed the STAThread attribute on the wrong method: it needs to be the method that the form is started from, not the method you are executing.
In many cases, your application will have a Sub Main and this is what needs to be decorated with the STAThread attribute. An example from MSDN:
Public Class MyForm
Inherits Form
Public Sub New()
Me.Text = "Hello World!"
End Sub 'New
<STAThread()> _
Public Shared Sub Main()
Dim aform As New MyForm()
Application.Run(aform)
End Sub
End Class
I want to run some processing-intensive code in a thread upon starting Excel, and have included a simplified example below. A call to clsInit.Main is the starting point. The code executed in this thread (Sub DoIt) then modifies a variable (rng) that will be saved for use later when I access it by calling Sub GetIt. It doesn't work. Why? Thanks for the help.
Imports System.Threading
Public Class clsInit
Shared Sub Main()
Dim t As New Thread(AddressOf clsTest.DoIt)
t.Start()
End Sub
End Class
Public Class clsTest
Private Shared rng As Excel.Range
Public Shared Sub DoIt()
rng = Globals.ThisAddin.Application.ActiveCell
End Sub
Public Shared Sub GetIt()
MsgBox(rng.Address)
End Sub
End Class