Pool Threading with changing parameters

emailstuff(5) is changing with the x but not changing in the threads.

        Dim emailstuff() As String = {"Name", "campusbox", "recievedate", "Shippingmethod", "Trackingnumber", "Packagetype", "Noticelevel", "", "emailaddress", "originator"}
        For x As Integer = 1 To 10
            System.Threading.ThreadPool.QueueUserWorkItem(AddressOf sendEmail, emailstuff)
            emailstuff(5) = x

Open in new window

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kyle AbrahamsSenior .Net DeveloperCommented:
Pass EmailStuff(x) as the parameter:

For x As Integer = 1 To 10
            System.Threading.ThreadPool.QueueUserWorkItem(AddressOf sendEmail, emailstuff(x))            

Open in new window

MillkindAuthor Commented:
I want each thread to have different parameters. Not just send the on parameter over and over.  Also the sub requires an array not a string.
Kyle AbrahamsSenior .Net DeveloperCommented:
Change sendEmail to accept a string and just pass emailstuff(x)

this will change every time because of the array with the counter.

The other thing you can do is pass in X and reference the array globally, but I wouldn't go that route.
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

What are you wanting to accomplish?  I think you have the wrong idea about what a ThreadPool is used for.  Consider the following:
Imports System.Net.Mail
Imports System.Threading

Module Module1
	Sub Main()
		Dim emails As New List(Of EmailStuff)
		For x As Integer = 0 To 9
			emails.Add(New EmailStuff() With {.Name = String.Format("Email{0}", (x + 1))})
		Console.WriteLine("Processing emails")
		Using countdown = New CountdownEvent(emails.Count)
			For x As Integer = 0 To emails.Count - 1
				Dim i As Integer = x
										    SendEmail(i + 1, emails(i))
									    End Sub, Nothing)
		End Using
		Console.WriteLine("Finished processing emails")
	End Sub

	Private Sub SendEmail(ByVal ID As Integer, ByVal Message As EmailStuff)
		Thread.Sleep(100 * ID)
		Console.WriteLine("Mail message {0} for {1} sent.", ID, Message.Name)
	End Sub
End Module

Class EmailStuff
	Public Property Name() As String
	Public Property CampusBox() As String
	Public Property ReceivedDate() As Date
	Public Property ShippingMethod() As String
	Public Property TrackingNumber() As String
	Public Property PackageType() As String
	Public Property NoticeLevel() As String
	Public Property Unused() As String
	Public Property EmailAddress() As MailAddress
	Public Property Originator() As String
End Class

''' <summary>Represents a synchronization primitive that is signaled when its count reaches zero.</summary>
''' <remarks>
''' <para>
'''   This class is similar to but less versatile than .Net 4's built-in CountdownEvent.
''' </para>
''' </remarks>
Public NotInheritable Class CountdownEvent
	Implements IDisposable
	Private ReadOnly _reachedZeroEvent As New ManualResetEvent(False)
	Private _count As Integer
	Private _disposed As Boolean

	''' <summary>Initializes a new instance of the <see cref="CountdownEvent"/> class.</summary>
	''' <param name="initialCount">The initial count.</param>
	Public Sub New(ByVal initialCount As Integer)
		_count = initialCount
	End Sub

	''' <summary>Signals the event by decrementing the count by one.</summary>
	''' <returns><see langword="true" /> if the count reached zero and the event was signalled; otherwise, <see langword="false"/>.</returns>
	Public Function Signal() As Boolean

		' This is not meant to prevent _count from dropping below zero (that can still happen due to race conditions),
		' it's just a simple way to prevent the function from doing unnecessary work if the count has already reached zero.
		If _count <= 0 Then
			Return True
		End If

		If Interlocked.Decrement(_count) <= 0 Then
			Return True
		End If
		Return False
	End Function

	''' <summary>Blocks the calling thread until the <see cref="CountdownEvent"/> is set.</summary>
	Public Sub Wait()
	End Sub

	''' <summary>Blocks the calling thread until the <see cref="CountdownEvent"/> is set, using a <see cref="TimeSpan"/> to measure the timeout.</summary>
	''' <param name="timeout">The timeout to wait, or a <see cref="TimeSpan"/> representing -1 milliseconds to wait indefinitely.</param>
	''' <returns><see langword="true"/> if the <see cref="CountdownEvent"/> was set; otherwise, <see langword="false"/>.</returns>
	Public Function Wait(ByVal timeout As TimeSpan) As Boolean
		Return _reachedZeroEvent.WaitOne(timeout, False)
	End Function

	''' <summary>Blocks the calling thread until the <see cref="CountdownEvent"/> is set, using a 32-bit signed integer to measure the timeout.</summary>
	''' <param name="millisecondsTimeout">The timeout to wait, or <see cref="Timeout.Infinite"/> (-1) to wait indefinitely.</param>
	''' <returns><see langword="true"/> if the <see cref="CountdownEvent"/> was set; otherwise, <see langword="false"/>.</returns>
	Public Function Wait(ByVal millisecondsTimeout As Integer) As Boolean
		Return _reachedZeroEvent.WaitOne(millisecondsTimeout, False)
	End Function

	''' <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
	Public Sub Dispose() Implements IDisposable.Dispose
	End Sub

	Private Sub Dispose(ByVal disposing As Boolean)
		If Not _disposed Then
			If disposing Then
				DirectCast(_reachedZeroEvent, IDisposable).Dispose()
			End If
			_disposed = True
		End If
	End Sub

	Private Sub CheckDisposed()
		If _disposed Then
			Throw New ObjectDisposedException(GetType(CountdownEvent).FullName)
		End If
	End Sub
End Class

Open in new window

Which produces the following output -Capture.JPGHere you can see that the idea behind a threadpool is to use a single thread for each item you want to process.  The idea here is that you have a limited number of threads that you can work on, when you reach this limit, you queue any additional work until a thread is released.  Once the thread is release, the ThreadPool grabs the next item from the queue and starts it's delegate.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MillkindAuthor Commented:
All the items in emailstuff will be different in each thread.  I only changed the 5th one for this as a test to see how to do it.  I am new to threading and the articles and tutorials were very confusing.  I believe i understand what a thread pool is in theory but not in practice.  Like why can't I change the input for each pass in the for loop?  Im going to work with the Module now.
MillkindAuthor Commented:
With a little tweaking it works wonderfully.  Also by doing the tweaking I have learned a little bit about threading.  It is easier to see it done then read about it sometimes.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.