Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Multithreading

Posted on 2001-08-03
8
601 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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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
 
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
VBA saving file message display 5 72
Visual Studio 2005 text editor 10 43
Protecting vb6 & .Net code Obfuscation 18 150
Zip Folders Using Chilkat Routines 1 58
Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

808 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