Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I am trying to get multithreading working for a project.

 

I have created a test app so I can figure out the multithreading without having to worry about other issues.

I have an arraylist that contains the numbers 1-100. I want to square those numbers and add them to a listbox. The problem I am having is that it runs though each thread one time and then it dies. I get errors about the thread unable to restart. I tried putting suspend and interrupt command in the background process but nothing helped so far. Any ideas?

Here is the code I am using:

 

Public ThreadControl1 As Thread = New Thread(AddressOf Me.BackgroundProcess)

Public ThreadControl2 As Thread = New Thread(AddressOf Me.BackgroundProcess)

Public ThreadControl3 As Thread = New Thread(AddressOf Me.BackgroundProcess)

Public ThreadControl4 As Thread = New Thread(AddressOf Me.BackgroundProcess)

 

Public SquareArrayList As New ArrayList

 

Public i As Integer

 

Private Sub BackgroundProcess()

listbox1.Items.Add(SquareArrayList.Item(i) & " " & SquareArrayList.Item(i) * SquareArrayList.Item(i))

i += 1

End Sub

 

Private Sub StartClick(sender As System.Object, e As System.EventArgs)

Do While i < SquareArrayList.Count

ThreadControl1.Start()

ThreadControl2.Start()

ThreadControl3.Start()

ThreadControl4.Start()

Loop

End Sub

Posted (edited)

Funny... I just started learning Threading just a few mins. ago and I'm struggling with some of the same issues. Here's what I've figured out so far:

 

(1) Don't use Thread.Sleep and Thread.Interrupt when called externally, as it seems a bit less "safe". Use Thread.Suspend and Thread.Resume instead.

 

(2) You must check the Thread.ThreadState before doing your commands. Why? Because if you call Thread.Start() again after it's already Running, then it will error out. Similarly, calling Thread.Suspend when it's already suspended would be a no-no..

 

So see the attached project that I was kicking around. It is really a noobie Threading project, to be sure... and represents 100% of my knowledge on this subject! (Yeah pretty weak...) But hopefully it will be of value to you.

 

The project itself is attached, but the code is pretty simple:

Public Class Form1
   Inherits System.Windows.Forms.Form

   Sub DoIt()
       For i As Integer = 0 To 1000000000
           Me.lblResults.Text = i.ToString("N0")
       Next
   End Sub

   Dim oThread As System.Threading.Thread

   Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
       If oThread Is Nothing Then
           oThread = New Threading.Thread(AddressOf DoIt)
           oThread.Start()
       End If
   End Sub

   Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
       If Not oThread Is Nothing Then
           If oThread.ThreadState = Threading.ThreadState.Suspended Then oThread.Resume()
           oThread.Abort()
           oThread.Join() ' <-- Edited thx to Wile's comment below. :-)
           oThread = Nothing
           Me.lblResults.Text = ""
       End If
   End Sub

   Private Sub btnSuspend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSuspend.Click
       If Not oThread Is Nothing Then
           If oThread.ThreadState = Threading.ThreadState.Running Then oThread.Suspend()
       End If
   End Sub

   Private Sub btnResume_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnResume.Click
       If Not oThread Is Nothing Then
           If oThread.ThreadState = Threading.ThreadState.Suspended Then oThread.Resume()
       End If
   End Sub
end Class

I have no doubt that the above approach is flawed... But baby steps, right?

 

Hope it helps...

Mike

vbThreadingExperiments.zip

Edited by Mike_R

Posting Guidelines

 

Avatar by Lebb

Posted
Funny... I just

If oThread.ThreadState = Threading.ThreadState.Suspended Then oThread.Resume()

oThread.Abort()

Do While oThread.ThreadState = Threading.ThreadState.Running

' Just wait.

Loop

oThread = Nothing

 

A tip: don't do this in production code :p. If the thread that is aborting takes some time to abort (e.g. it has to clean up some heavy resources like bitmaps, database connection, handles, whatever), the loop will make sure the CPU is well and truely kept busy.

Better would be to join the thread after the abort: oThread.Join(). This will still halt your code until the thread is finished with the abort, but it won't cause 100% cpu load ;).

Nothing is as illusive as 'the last bug'.
Posted
I am trying to get multithreading working for a project.

 

Private Sub StartClick(sender As System.Object, e As System.EventArgs)

Do While i < SquareArrayList.Count

ThreadControl1.Start()

ThreadControl2.Start()

ThreadControl3.Start()

ThreadControl4.Start()

Loop

End Sub

 

i believe this is your problem running the 4 threads is not a problem but when you loop you are trying to start a thread that is already running, hence the error.

 

if you were wanting a dynamic number of threads maybe try creating a collection of threads and adding a new one when required.

 

   Public MyThreads As New ArrayList

   Sub main()
       For i As Integer = 0 To NumberofThreadsRequired
           AddThread()
       Next
   End Sub

   Private Sub AddThread()
       Dim MyNewThread As New Thread(AddressOf MyMethod)

       MyThreads.Add(MyNewThread)

   End Sub

   Private Sub MyMethod()
       'Do some stuff
   End Sub

Posted (edited)
A tip: don't do this in production code... Better would be to join the thread after the abort: oThread.Join(). This will still halt your code until the thread is finished with the abort' date=' but it won't cause 100% cpu load ;).[/quote'] Thanks Wile, yeah, I was fairly hesitant to post at all given my complete lack of experience in this... I knew others would have better ways of handling this!

 

I did notice Thread.Join(), but wasn't quite sure how it would work... Thank you for explaining it. :)

 

[Edit: And I've now edited my code, above...]

Edited by Mike_R

Posting Guidelines

 

Avatar by Lebb

Posted
mattsrebate...Technically you are not supposed to use objects or values type defined outside the current thread (ie. i and listbox1). Instead create a class around the thread function and store the counter variable as a property. For this program I would bind an event to the thread function and raise it when it the thread is exiting, when the event is raised, restart the thread (or not depending on the condition).
Posted (edited)

Multithreading out of control now

 

i believe this is your problem running the 4 threads is not a problem but when you loop you are trying to start a thread that is already running, hence the error.

 

if you were wanting a dynamic number of threads maybe try creating a collection of threads and adding a new one when required.

 

I took your advice and made it dynamic. I created a thread to control the worker threads. The controller thread (ThreadController) only purpose is to spawn worker threads (ThreadWorker). The problem I am encountering now is that the number of threads is out of control. I know why (because of the loop in my code) but can't think of a way to make it behave. I also need to put a synlock in the code but I did not know how to do it. Any advice is greatly appreciated. Here is the code that is giving me the trouble:

 

 
   Public ThreadController As Thread

   Dim i As Integer = 1
   Dim j As Integer = 20000

   Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click
       ListBox.Items.Clear()

       StartButton.Enabled = False
       StopButton.Enabled = True
       PauseResumeButton.Enabled = True

       ThreadController = New Thread(AddressOf Me.ControlThreads)
       ThreadController.Start()
   End Sub

   Private Sub ControlThreads()
       Do While i < j
           For k As Integer = 1 To ThreadCountNumericUpDown.Value
               AddThread()
           Next
       Loop

       If i = j Then
           StartButton.Enabled = True
           StopButton.Enabled = False
           PauseResumeButton.Enabled = False
       End If
   End Sub

   Private Sub AddThread()
       Dim ThreadWorker As Thread = New Thread(AddressOf Me.BackgroundProcess)
       ThreadWorker.IsBackground = True
       ThreadWorker.Start()
   End Sub

   Private Sub BackgroundProcess()
       ListBox.Items.Add(i)
       i += 1
   End Sub

   Private Sub PauseResumeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PauseResumeButton.Click
       StartButton.Enabled = False
       StopButton.Enabled = True
       PauseResumeButton.Enabled = True

       If ThreadController.ThreadState = 64 Then
           ThreadController.Resume()
       Else
           ThreadController.Suspend()
       End If
   End Sub

   Private Sub StopButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopButton.Click
       StartButton.Enabled = True
       StopButton.Enabled = False
       PauseResumeButton.Enabled = False

       If ThreadController.ThreadState = 64 Then
           ThreadController.Resume()
       End If
       ThreadController.Abort()
       ThreadController.Join()
   End Sub

   Private Sub ExitButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitButton.Click
       Me.Close()
   End Sub

MultiThreadtest.zip

Edited by PlausiblyDamp

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...