Thread issue

F

fniles

I create a thread where I pass thru a message. When I click very fast many
times (like 50 times) to create 50 threads, the message did not get pass
thru ProcessMessage.
For example: strBuffer = "#TRADE, D1410-123456, BUY, 1, ESM7, DAY, LIMIT,
1490.00, , , 0, 0, 0, 0, 0, links |52994/25/2007 10:47:17 AM !A", when I
trigger to create many threads (like 50), this message did not get to sub
ProcessMessage in clsEachMessage.
I have added Thread.Sleep(0) after the Start method of the thread.
What is the best way to do the thread so that every message get pass thru to
it ?
Is there a maximum number of thread that I can create ?
Shall I use thread pool instead of creating a new thread each time ?
Thank you very much.

Dim EachMessageThread As Threading.Thread = Nothing
Dim clsEachMessage As New EachMessage

clsEachMessage.sMessage = strBuffer
EachMessageThread = New Threading.Thread(AddressOf
clsEachMessage.ProcessMessage)
threadCount += 1
EachMessageThread.Name = "Thread " & threadCount.ToString()
EachMessageThread.Start()
Thread.Sleep(0)

Public Class EachMessage
Public sMessage As String

Public Sub ProcessMessage()
Dim swError As StreamWriter

swLog = New StreamWriter(sPath & "\log\Input.txt", True)
swLog.Write(sMessage & vbCrLf)
swLog.Close()
swLog = Nothing
 
B

Branco Medeiros

fniles wrote:
<backposted/>

I don't think the problem has to do with you creating threads in a
rapid (!) sequence. It seems to me it has more to do with the lack of
synchronization between your threads when accessing the file.

The problem is that I can only suppose what is really going on,
because the code you posted is incomplete and has some logical
inconsistencies (I assume you typed the code directly in the message
instead of copy-pasting).

Anyway, it becomes somewhat evident that you want to create a
multithreaded log system. If this is the case, then you must consider
that logging must respect a first in, first out sequence. Also,the
file system may complain of multiple writing attempts from different
threads to the same file. Both issues require some sort of thread
synchronization.

A possible approach would be to have a logging class that each thread
shared (instead of creating a different class for each thread).
Something in the lines of:

<code>
Public Class Log
Private mLogFile As String
Public Sub New(ByVal Path As String)
mLogFile = Path
LogMessage("")
End Sub

Public Sub LogMessage(ByVal Text As String)
SyncLock Me
System.IO.File.AppendAllText(mLogFile, Text)
End SyncLock
End Sub

End Class
</code>

You can test the class with the following:

<aircode>
'At module or class level
Const LOG_PATH = "..."
Private mLog As New Log(LOG_PATH)

'...
Sub SaveMessage(Msg As Object)
Static Random as New System.Random
Dim T As Integer
SyncLock Random
T = Random.Next(50, 300)
End SyncLock
System.Threading.Thread.Sleep(T)
mLog.LogMessage(Msg.ToString & ControlChars.CrLf)
End Sub

Sub TestLog
For I As Integer = 1 to 50
Dim Msg As String= "Message #" & I.ToString
Dim T As New System.Threading.Thread(AddressOf SaveMessage)
T.Start(Msg)
Next
End Sub
</aircode>

HTH.

Regards,

Branco.
 
F

fniles

Thank you for your reply.
I actually do not want to create a log system. In my sample code, I write to
a log file to check what string I receive in the thread.

Your method creates the class once that each thread shared, instead of
creating a different class for each thread. Will it be a problem if I create
a different class for each thread ? Will it be slower ?
If I create a different class for each thread then call threadpool like the
following, is that ok ?
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf
clsEachMessage.ProcessMessage))

Thank you.
 
F

fniles

How about if I do not use class, but using the threadpool like the
following:
Public Class ClientSession
Dim strBuffer As String

ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ProcessMessage),
strBuffer)

Public Sub ProcessMessage(ByVal Data As Object)
sMessage = CType(Data, String)
:
end Sub

end Class
 
F

fniles

1 more question.
If I create only 1 class that each thread shared, and the class has many
module level variables (in the example below Account and Quantity). That
module level variable is modified by each thread, since the class is shared
by each thread, will the value of these module level variables be correctly
assigned to the correct thread ? Thank you.

For ex:
Dim clsEachMessage As New EachMessage

Do While Not Terminated
:
clsEachMessage.sMessage = strBuffer
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf
clsEachMessage.ProcessMessage))
Loop

Public Class EachMessage
Public sMessage As String
Private Account As String -> module level variable
Private Quantity As integer-> module level variable

Public Sub ProcessMessage(ByVal stateInfo As Object)
Account = ... -> this module level variable is modified in each
thread, since the class is shared by each thread, will this value be
correctly assigned to the correct thread ?
Quantity = ... -> this module level variable is modified in each
thread, since the class is shared by each thread, will this value be
correctly assigned to the correct thread ?
end sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top