Solved

Multithreading

Posted on 2001-08-03
8
598 Views
Last Modified: 2008-03-06
I have a program that listens to MSMQ messages and preforms database updates depending on messages. I want to build a monitor program that would display the arrived message on a form and also provide the user with ability to click on the buttons on this form at ANY time (even when my component is listening for MSMQ messages. I assume I have to put this component in a separate thread from the monitor application. How do I do it? I need details explanation and possible links with examples.

Thank you
0
Comment
Question by:ZhenyaT
8 Comments
 
LVL 22

Expert Comment

by:CJ_S
ID: 6347900
You can create an out-of-process component, which checks for the events. Then whenever the client application needs to be notified you use the an event.

Public Event MyEvent(...)

and raise it using
RaiseEvent MyEvent(the paramaters necessary)

Then in your client application you use something like:
Public WithEvents MyVar as COMPPROJECT.CLASSNAME

Private Sub MyVar_MyEvent(...)

End Sub


How to monitor the MSMQ messages I have no idea, but I suppose you can somehow retrieve them...no experience in that part)

regards,
CJ
0
 

Author Comment

by:ZhenyaT
ID: 6347920
CJ:

I have the MSMQ working and that's what ive done - an out-of-process component. Unfortunatelly it doesnt work! I must be doing something wrong. What happens is that as soon as the outofprocess component enters say a loop, my monitor client blocks! When I click on it, windows brings up a message with switch to and retry options.
0
 
LVL 1

Expert Comment

by:fparie
ID: 6348072
What you need to do is make the out of process component return immediately when handling the event. I usually achieve this type of thing by using a timer which i set active in the event handler and then return from the call. Whatever happens in the timer event will not block your other components. I can provide you with a 'code only' timer (messing around with forms and control is risky in this type of component).

Francois.
0
 
LVL 22

Expert Comment

by:CJ_S
ID: 6348146
Make it an ActiveX EXE... and connect to it using GetObject("", "BLAH.BLOEH")

Regards,
CJ
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 7

Accepted Solution

by:
Z_Beeblebrox earned 300 total points
ID: 6348676
Hi,

Why do you need to make it out of process. Can't you listen to the queue using events? If a message arrives on the queue, you can be notified, so you don't need to poll.

'Globals
Dim Queue As MSMQQueue
Dim WithEvents QueueEvent As MSMQEvent

'form load
Dim qinfo As MSMQQueueInfo
Set qinfo = New MSMQQueueInfo
   
qinfo.PathName = "pathofsomequeue"
Set Queue = qinfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)
Set QueueEvent = New MSMQEvent
Queue.EnableNotification QueueEvent, Cursor:=MQMSG_CURRENT

'queue event handler
Private Sub QueueEvent_Arrived(ByVal Queue As Object, ByVal Cursor As Long)

' Do whatever

End Sub



Zaphod.
0
 
LVL 3

Expert Comment

by:adg
ID: 6349799
Here is an example of multithreading in VB. This program reads 3 text files on 3 different threads.  I added a project reference to Microsoft Scripting Runtime to use File System Objects to access the files.

Timers on forms are used to kick off the threads asynchronously so the files process at the same time.
A form is also used to identify the first time though, since main is automatically called every time
a thread is created.

Even though the threads in this example process the files "independently", any communication between threads is still syncronized via COM which reduces application responsiveness.  If you are interested I can post an example of communicating between threads outside of COM control but in that case you will have to ensure that your threads don't update variables simultaneously.  

VB 6 is not very friendly to multithreading applications.  

==============================================
' MainModule.bas

' ActiveX EXE Name = MTNF
' Startup Object = Sub Main
' Threading Model = Thread per Object
' Start Mode = Standalone
' !!! Must compile and run outside IDE !!!

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal

lpWindowName As String) As Long
Private frmMainThreadForm As MainThreadForm
Private Const PROC_CAPTION = "MTNF Main Thread Form"
Private Thread1  As ProcessFileObject

Sub Main()
  If 0 = FindWindow(vbNullString, PROC_CAPTION) Then
      'MsgBox "Main = " & Hex(App.ThreadID)
      Set frmMainThreadForm = New MainThreadForm ' create first form on pre-existing thread
      frmMainThreadForm.Caption = PROC_CAPTION
      Set frmMainThreadForm = Nothing 'don't need this reference, form loads itself and stays alive
until unloaded
  End If
End Sub

Public Sub CreateThreads()
 Set Thread1 = CreateObject("MTNF.ProcessFileObject")
 Thread1.ProcessFile "a.txt"
 '
 Set Thread1 = CreateObject("MTNF.ProcessFileObject")
 Thread1.ProcessFile "b.txt"
 '
 Set Thread1 = CreateObject("MTNF.ProcessFileObject")
 Thread1.ProcessFile "c.txt"
 Set Thread1 = Nothing
End Sub

Public Sub ReportRecordCount(FileName As String, RecCount As Long)
  MsgBox FileName & " contains " & CStr(RecCount) & " records. Reported by Thread " & Hex(App.ThreadID)
End Sub

==============================================
' MainThreadForm.frm

Private Sub Form_Initialize()
   Timer1.Interval = 100
End Sub

Private Sub Timer1_Timer()
  Timer1.Enabled = False
  CreateThreads
  Unload Me
End Sub

==============================================
' ProcessFileObject.cls

Private frmTimerForm As TimerForm
 
Private Sub Class_Initialize()
  'MsgBox "Worker = " & Hex(App.ThreadID)
End Sub

Public Sub ProcessFile(FileName As String)
  Set frmTimerForm = New TimerForm
  frmTimerForm.SetOwner Me
  frmTimerForm.StartTimer FileName
End Sub

Public Sub RecordCount(FileName As String)
  ' add project reference to Microsoft Scripting Runtime
  ' to use File System Objects
  Dim fso As New FileSystemObject
  Dim fil1 As File
  Dim ts As TextStream
  Set fil1 = fso.GetFile(FileName)
  Set ts = fil1.OpenAsTextStream(ForReading)
  ts.ReadAll
  ReportRecordCount FileName, ts.Line
  ts.Close
  Set frmTimerForm = Nothing
End Sub
==============================================
' TimerForm.frm

Private objOwner As ProcessFileObject
Private strFileName As String

Public Sub SetOwner(objRef As ProcessFileObject)
  Set objOwner = objRef
End Sub

Public Sub StartTimer(FileName As String)
  strFileName = FileName
  Timer1.Interval = 55
End Sub

Private Sub Timer1_Timer()
  Timer1.Enabled = False
  objOwner.RecordCount (strFileName)
  Set objOwner = Nothing
  Unload Me
End Sub
0
 

Author Comment

by:ZhenyaT
ID: 6354531
CJ:

I have the MSMQ working and that's what ive done - an out-of-process component. Unfortunatelly it doesnt work! I must be doing something wrong. What happens is that as soon as the outofprocess component enters say a loop, my monitor client blocks! When I click on it, windows brings up a message with switch to and retry options.
0
 

Author Comment

by:ZhenyaT
ID: 6354654
Cheers dude, awesome idea...dunno why I didn't think of it...

one thing you missed out is you need to receive the message every time it arrives and then reset the EnableNotification.

Thanks a lot.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now