Link to home
Start Free TrialLog in
Avatar of vinaikk
vinaikk

asked on

want to muti thread a Socket Prorgrame in VB

i want to do create a software which will listedn to a specific port and get date in xml from the client and processes it and returns back and xml stream.  I have used win sock ocx and created an array to accept multiple connections.  now i want to make it mulit threade it.  how can i do it in vb.  The entire stuff will be executed on a windows 2000 Server having SQL server 2000 as the back end database.  Alos note that that the processing of client request may take some time (approx 10-20 secs or more )
ASKER CERTIFIED SOLUTION
Avatar of adg
adg

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of xorcrack
xorcrack

i'm just learning vb.net and noticed that it handles multithreading real simply by using something called "delegates". if it is not too much trouble you should consider vb.net.
I agree partially with adg

>>Multi-threading in VB6 is ugly

It is true if you run single program


Another alternative is create a new activeEXE and wrap around the OCx call

And then call this activeEXE from your main program

you can create activeEXE as many as you want and because it is out-of process. It seems as running multi-threading VB
Avatar of vinaikk

ASKER

i guess you are right, ActiveX exe would be the best to use.  
Request you to help me in this (ActiveX EXE)
You can mail me at
vinai.karunakaran@ext.icicibank.com

will be waiting for your reply, it is quiet urgent

Regards
Vinai KK
Hi, thanks for accepting my "answer".  Rather than working with you via email, I'll post to this thread and then I'll try to help you with the inevitable problems you'll have getting it to work. I'll post a multithread example (as a starting point) a little later today.
Here is an example of multi-threading in VB6. The thread id is displayed to verify that it is multithreaded. It has to be an activex exe project.  It has to be complied. If you run it in the IDE, it should execute OK but it won't be multithreaded. See the comments below for the proper project settings - it won't work without them.  Also, communication between threads is automatically synchronized by VB (COM) so trying to pass information between threads is a bit of a problem. The application has to be architected very carefully or you'll lose the benefits of having multiple threads.

In this example, the main thread will create three worker threads and pass each of them the name of a different text file. Each of those threads will read their assigned file and report the number of records found. I added a project reference to Microsoft Scripting Runtime to use File System Objects to access the files.

A word about object reference management.  The main thread only uses a single object variable (Thread1) to create three threads and then sets it to nothing.  In other words it isn't retaining a reference to the worker threads. Also note that the ProcessFile proc uses a timer to kick off the long running proc and that the timer is running on the worker thread. Its purpose is to allow the call to return to the main thread right away - otherwise the main thread would stop and wait for the worker thread to complete.  

I hope this helps - let me know if you run into a snag and I'll try to assist.  
==============================================
' MainModule.bas
Option Explicit
' 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 = Nothing
  '
  Set Thread1 = CreateObject("MTNF.ProcessFileObject")
  Thread1.ProcessFile "b.txt"
  Set Thread1 = Nothing
  '
  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
Option Explicit
Private Sub Form_Initialize()
    Timer1.Interval = 100
End Sub

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

==============================================
' ProcessFileObject.cls
' Instancing=Multiuse <=====
Option Explicit
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
Option Explicit
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
Avatar of vinaikk

ASKER

I tried doing as you said, but that doesn't suffice, actually iam expecting such things
1. There will be a main executable which listens to a socket
2. if an connection request is detected theni will create and object of the ActiveX EXE and ask it to Accept it by passing the discriptor
3.  Then the main executable will be free to take other connection requests
4. The object of ActiveX EXE created in step 2 will be serving a clinet till the client sends a siginal for Termination of Channel
---------------------
I tried the same with OCX it is happening, but since it is an In Proc server it may create a problem. I tried to do it with ActiveX EXE  but it is not accepting the connection

REquest your advice on the same