StackOverFlow Exception using Background Thread in vb.NET - vb.net

i'm using a background Thread in vb.net to connect/reconnect to a device.
It's working fine, but after around 2 hours, the programm is throwing a stackoverflow exception, in the following part of my code:
if connected = True then
Thread.Sleep(500)
Exit sub
endif
After that, i'm calling the Sub again.
I know, i could just set the Sleep-Time to e.g. 1000 ms, but i think this isnt the nicest solution...
Would a "Backgroundworker" (using visual studio) be the better solution/ solve my Problem?
Or is there a posibility to clean the stack?
Thanks for your help!
EDIT:
Module connection
Public Sub connect()
connect_loop()
connect()
End Sub
Public sub connect_loop()
if connected = True Then
**HERE IS WHERE THE EXCEPTION IS THROWN**
Thread.Sleep(500)
Exit Sub
Endif
'Code for the Connection (ping, open Socket etc.)....
End Sub
End module
The module is started from my main routine as a background thread:
Public background As New Thread(AddressOf connection.connect)
background.IsBackground = True
background.Start()
Do you need the Code for the connection? I didn't wrote it here, because the Exception is not thrown in the real connection part. Also, 2 hours everything works fine.

Your method connect is recursive without any condition under which it will return.
Each call to a function or method will make use of some stack space, and each thread only has so much stack space.
If you want connect to loop for ever just use an infinite loop (but consider how the lop will exit when you want to stop the process).

Public Sub connect()
...
connect()
End Sub
So which part of the obvious stack overflow is unclear to you? You are calling connect recursively w/o any criteria. It will stack overflow, guaranteed. Your Sleep() only delays the inevitable. Threading has nothing to do with the problem. You may want to do somehting like a loop instead:
while(true)
connect_loop()
end
(or whatever is the VB syntax for a while loop).

Related

VB.Net Multi-Threading InvokeRequired and Passing Thread

I need to be able to pass the thread name into a subroutine in order to abort it when I need to.
So I have this so far:
Dim BrowserSpawn As New System.Threading.Thread(AddressOf BrowserSub)
BrowserSpawn.Start()
Private Async Sub BrowserSub(BrowserSpawn)
...
End Sub
Because the subroutine creates a browser within Form1 groups I needed to invoke access to these controls within the sub.
Note: This works fine when I'm not passing in the thread name.
If Me.GroupNamehere.InvokeRequired Then
Me.GroupNamehere.Invoke(New MethodInvoker(AddressOf BrowserSub))
Else
'Do nothing
End If
When I'm passing in the thread name these become a problem when trying to compile:
Method does not have a signature compatible with delegate 'Delegate Sub MethodInvoker()'.
I'm hoping this is just a syntax thing but I can't seem to get it to work. Is there any way I'm able to pass in this thread name without breaking my invokerequired check?
If I try and change it to the obvious:
Me.GroupNamehere.Invoke(New MethodInvoker(AddressOf BrowserSub(BrowserSpawn)))
It tells me Addressof operand must be the name of a method (without parentheses). Although without the parentheses it's not happy either so I don't know where to go from here.
/edit:
Stumbled across How can I create a new thread AddressOf a function with parameters in VB?
Which seems to confirm what I was trying passing something like:
Private Sub test2(Threadname As Thread)
' Do something
End Sub
And the sub seems happy with that. But I'm not sure how to do that without breaking the invoker part.
Me.GroupNameHere.Invoke(New MethodInvoker(AddressOf SubNameHere))
Works normally. If SubNameHere() becomes SubNameHere(threadname as thread) then that seems happy enough but the invoke line breaks and doesn't want more than the address of.
Two slight syntax changes sorted it:
Private Async Sub SubName(ThreadNameAs Thread)
and
GroupName.Invoke(New MethodInvoker(Sub() Me.SubName(ThreadName)))

My program in vb.net often end abruptly. How to find end command?

I think there is an end command somewhere that I miss and got called.
However, how to find it.
If I search for end then there are so many end. End sub, end function.
I just want the program to break just before abruptly end.
Is this because of some out of memory or what?
The program run in debug mode. Suddenly it ends. So it runs 100 threads and then the vb 2012 is still running but the program have stopped. As if someone press the stop button or some end statement reached.
Depending on your technology stack, try overriding the OnExit method:
protected override void OnExit(ExitEventArgs e) {
base.OnExit(e);
}
Set a break point on the base.onExit(e); line and then look in the call stack. Or if you aren't in the debugger, write to a message box the previously called method.
If you want to find End and ignore End Sub etc. you can search using regular expressions (Ctrl+F Alt+E)
End\r?$
Finds End at the end of a line. Interestingly, it's exactly the example in the MSDN regex page

VB.NET Service Skipping Over Sub Procedure

I'm writing a Windows Service in VB using Visual Studio 2010. The service is going to check for changes to a table in a database every minute or so. I have experience with VB6 but am new to both VB.NET and creating services, so I might be overlooking something obvious here. When the service is stopped, paused, started, or resumed, a sub procedure is supposed to be called. The problem is that the program skips right over the call to the sub procedure. I set break points at OnPause() and OnContinue() and stepped through the code, to confirm that the program is skipping right over the calls to AgentStopped() and AgentStarted(). What am I doing wrong?
Protected Overrides Sub OnPause()
Log.WriteEntry("Agent paused.") 'This is written to the log
AgentStopped() 'This line is skipped
End Sub
Protected Overrides Sub OnContinue()
Log.WriteEntry("Agent restarted.") 'This is written to the log
AgentStarted() 'This line is skipped
End Sub
Private Sub AgentStarted()
Log.WriteEntry("AgentStarted called.") 'This never written to the log
End Sub
Private Sub AgentStopped()
Log.WriteEntry("AgentStopped called.") 'This never written to the log
End Sub
As you understand, there is no way for the lines you imply to be skipped since the containing method is called. Something else is happening. I suppose the code you are showing is simplified. Right?
I would bet that either you are running a wrong version of your code by mistake, or on your real code an exception occurs inside the called methods (AgentStarted and AgentStopped).
In order to debug this, I would follow these steps:
Change the current log messages and add messages after the call to the functions
Protected Overrides Sub OnPause()
Log.WriteEntry("Agent pause beginning.")
AgentStopped()
Log.WriteEntry("Agent pause ending.")
End Sub
Protected Overrides Sub OnContinue()
Log.WriteEntry("Agent restart beginning.")
AgentStarted()
Log.WriteEntry("Agent restart ending.")
End Sub
If you see the new messages, you will be able to verify that you are actually running the right version of the code and not an older version deployed by mistake.
You should use exception handling with try - catch. I am not really sure (I have never used it), but perhaps using the UnhandledException event to get info for possible uncaught exceptions could be helpful. Another option would be to check the windows event log for errors occuring while executing a web service.
Hope I helped!

Threading. How does button click interrupt/influence program flow

My project is vb.net 2010 windows desktop form.
So far, single threaded (default).
If a SUBroutine has a for...next loop in it that is running, what happens if a buttonclick event is fired and within that event a variable is changed? Like: does program execution leave the loop that was running? Or does it continue to run while that variable is changed by the buttonclick event?
What I'm aiming for:
If someone clicks the button, blnRequestStop is set to True.
Within that for...next loop, just before the "next" it checks blnRequestStop. If true then it will exit the "for" loop.
I'm guessing I need to use threads? Can anyone give me a simple example, please?
EDIT:
This code below seems to be working fine. But maybe you all see a problem?
If (btnProcess.Text = "Done!") Then
End
ElseIf (btnProcess.Text = "IMPORT") Then
bRequestStop = False
t1 = New Thread(AddressOf ProcessDo)
t1.Start()
Else
t2 = New Thread(AddressOf MyInterrupt)
t2.Start()
End If
Here is the short version of what ProcessDo and MyInterrupt do:
Private Sub ProcessDo()
For each X in blahblah
'do stuff (yes, includes interface)
if (blnInterrupt) then exit For
Next X
End
End Sub
Private Sub MyInterrupt()
blnInterrupt=true
End Sub
Yes, you probably want to do the long-running task on a background thread. Here's a code sample including how you'd get the results back to the UI thread when you're done (otherwise you'll get errors about Cross-thread operation not valid).
ThreadPool is a nice way to do some work on a background thread. You could set stopIt = True in the button click event for the stop button.
ThreadPool.QueueUserWorkItem(
Sub()
For Each thing In things
If stopIt Then Exit Sub
'Do the stuff!
Next
'We're done, update UI
Me.UpdateUI("All done!")
End Sub)
To safely update the UI, you'll need to make sure you get back to the UI thread.
Public Sub UpdateUI(result As String)
If Me.InvokeRequired() Then
'If we aren't on the UI thread, invoke this function on the UI thread
Me.BeginInvoke(Sub() UpdateUI(result))
Exit Sub
End If
'Update UI here
lblResult.Text = result
End Sub
Execution is 'stopped' (in a way) until the Loop finishes him job, so yes, you need to multi-thread.
It it is not a very long operation where you need to update UI controls during the Loop then you just can use Application.DoEvents inside the loop to be able to use other controls as normally in the application when FOR loop is working, but I advise you that this will have a negative impact on UI performance, but if it's not a long duration loop then you maybe would consider to use DoEvents instead introduce into multi-threading it's just an alternative, not recommended but, you can use it.
PS: Forgive my English

VB.Net App Stuck in Loop

I would just like the program to end itself.
Application.Exit just keeps rolling me back in a loop.
EDITED to Include Code::
Module Module 1
Sub Main()
Sub1()
Sub2()
End Sub
Sub1()
EndSub
Sub2()
End Sub
End Module
EDIT: It seems to be looping back here to Sub ChooseDomain2.. I am including Sub 1 as well.
Sub ChooseDomain1()
Dim DomainName As Object
'Get List of all users on Domain using WinNT
DomainName = InputBox(messageOK, Title, defaultValue)
de.Path = "WinNT://****".Replace("****", DomainName)
If DomainName Is "" Then ChooseDomain2() Else StoreUserData1()
End Sub
Sub ChooseDomain2()
MsgBox("Welcome to the Domain Searcher. Click OK to Auto Search for Domain")
Dim MsgBoxResult As Object = ActiveDirectory.Domain.GetCurrentDomain.Name
MsgBoxResult = InputBox(messageCan, Title, MsgBoxResult)
de.Path = "WinNT://*****".Replace("*****", MsgBoxResult)
StoreUserData1()
End Sub
When it hits end Module it Just starts back from Square one.
Modules don’t execute at all – so it never “hits end module” and never starts “from square one”. Modules merely group methods that can be executed, and Main is a special method that serves as the start of your application.
That said, your code is guaranteed (!) not to execute repeatedly. Also, there is no Application.Exit anywhere in your code so it’s hard to see what you are actually executing. Not the code you showed, anyway.
Note that VB potentially executes code that you didn’t write (code can be auto-generated by the compiler, in particular the application framework) but this doesn’t seem to be happening in your case, and shouldn’t loop in any case. But again, this is impossible to say from the information you have given.
Application.Exit is not required as the console app will quit after it finishes executing the last line in Sub Main. As previously mentioned it is likely you have Sub1 calling Sub2 (or something similar), so set a breakpoint on the start of each sub to find which one is continually being called. Then you can do a search in your code to find where this sub is being called from.