Solved

Winsock & Multithreading

Posted on 2000-04-03
32
425 Views
Last Modified: 2013-12-25
I need to be able to download page using the winsock control from many place at the time, then analyse what is written on them then download another one. That mean I must use multithreading. How can I do so ?

April 9th, 22:00 US Est
I would need to know how I could create a new class that I could call, in which it would 1 download file from the web using winsock control then check what it got to download further URL. I also need to call many of them at the same time and be able to monitor the process..
0
Comment
Question by:PIBM
  • 19
  • 12
32 Comments
 
LVL 10

Accepted Solution

by:
caraf_g earned 150 total points
ID: 2682931
Threading without rocket science.

http://homepage.eircom.net/~carafa/TEMP/AWXB.zip

Explanation / order of compilation
AWXB02MSG.exe - (ActiveX.exe, one thread for all objects) Messaging application that will take care of sending messages between spawned threads and the main application.
AWXB01Thread.dll - The code that will be run in each separate thread
AWXB04Starter.exe - (ActiveX.exe, one thread per object) Application that will take care of creating each new thread.
AWXB03Test.exe - Standard exe. Main application / test bed.

Hope this helps.
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2682937
The above is simply an example, you can adapt it to suit your needs.

Don't hesitate to ask questions if anything's not clear!
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2682938
PS - the code only works for VB6. I recommend you use SP3 on that.
0
 

Author Comment

by:PIBM
ID: 2683953
I have VB5 SP3
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2684007
OK.... Knock wood.... but I think the code may actually work OK in VB5.... Only way of knowing is by giving it a go.

The cincher will be AWXB04Starter.exe; I'm not sure whether you can actually set the threading model of an ActiveX .exe to One thread Per Object in VB5. If you can, I'm hopeful that you'll be able to get this working.
0
 

Author Comment

by:PIBM
ID: 2684055
Currently I made my program that get the page and analyse the whole thing ..

it's like

Data = GetURL(...)
URL = Analise(Data)
DoEvents
Data = GetURL(URL)
URL = Analise(Data)
DoEvents
Data = GetURL(URL)

etc...

When I click many times on the command button it will start many at the same time, but will run the first part of the first click, stop at the doevents, do the first part of the second click, stop at do event, do the whole third one, complete the whole second one, then complete the whole first one.

Can I make them all work together with your program ?
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2684094
In theory, yes. It will require a bit of work on your part though. It's merely a framework.

Anyway, see if you can get it to run in VB5. If you can, that's great. Then have a look at it and if you have any questions, just post them here and I'll try to explain.

Pino
0
 

Author Comment

by:PIBM
ID: 2684113
Ok. I don't think I'll have the time to do that tonight but maybe tomorrow. See you later ( Currently at school - 10:30 am for me )
0
 

Author Comment

by:PIBM
ID: 2685212
if you got another idea than his please tell me =)
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2685410
whose? :o)
0
 

Author Comment

by:PIBM
ID: 2685649
anyone else who may read it.
I have not been able to run your program, I get some exceptions things

with the createthread command I've been able to create new thread but when I try to use ado to open a database VB hangs with a stack error
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2687237
PIBM, you weren't trying to run the compiled applications were you? They're VB6 applications and they won't work.

Even if you're recompiling the applications, may sure you do not use binary compatibility. Recompile them with no compatibility and re-set the references of the other projects. That way you can ensure that the whole suit is compiled as and will run as "vanilla" VB5.

Hope this helps.

Otherwise, can you tell me where and when the exception occurs, it may give me an idea where VB5 and VB6 are incompatible and how to adapt the code to work for VB5.

Cheers

Pino
0
 
LVL 2

Expert Comment

by:gelog
ID: 2689353
Hi PIBM,

Winsock Control is a multithreading component. I do not see your code here, but I'm sure that you can solve your problem using several instances of the Winsock Control. You can build a control array in run time or put communication code to a class module that ecapsulates the Winsock Control calls, and create an instance of the class for a new download task.

Welcome to http://www.vbip.com
0
 

Author Comment

by:PIBM
ID: 2689856
Hello Gelog.
 My program must run without user intervention and continually download data on many winsock controls at once that I create using Load Winsock(Getfreenum). The thing is if I start three request I get ...

winsock1 page 1
winsock2 page 1
winsock3 page 1
winsock3 page 2
winsock3 .......
winsock3 lastpage
winsock2 page 2
winsock2 .......
winsock2 lastpage
winsock1 page 2
winsock1 .......
winsock1 last page.

Meaning that it must wait for the latest started winsock control to finish the whole thing even if the connection is lowly used before continuing the previous process. You think that what you said would do it ?
0
 

Author Comment

by:PIBM
ID: 2691582
Any of you got ICQ ?
PIBM - 2452361
0
 

Author Comment

by:PIBM
ID: 2691588
Could I have more information about the class thing ?
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 10

Expert Comment

by:caraf_g
ID: 2692501
Hi PIBM, who is that question directed at? If it's directed at me, sure... what do you need to know?
0
 

Author Comment

by:PIBM
ID: 2697220
If that can fix my problem, how do I do that ?
0
 

Author Comment

by:PIBM
ID: 2698626
How do I create new classes using the winsock control in it ?
0
 

Author Comment

by:PIBM
ID: 2698839
Edited text of question.
0
 

Author Comment

by:PIBM
ID: 2702053
Caraf_g I got VB6 so I'm gonna try to run your thing ( Been able to get a bit of it to work under VB5 but the ADO controls where acting strangely so it should be ok now, at least I hope !)
0
 

Author Comment

by:PIBM
ID: 2702456
Ok I got it to work, not flawlessly but still it works =)
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2703119
Excellent! Do I deserve some points for that then?
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2703126
PS - if you are thinking about giving me a grade less than "A", please don't... In that case I would prefer it if you would not accept any of my comments here and delete this question.

In that case you could however post a dummy question "for caraf_g" with less than 100 points.

Thanks

Pino
0
 

Author Comment

by:PIBM
ID: 2704304
Your program is working perfectly. I've been able to do everything I want with it but I don't understand everything. I've found how the messages are sent and all that stuff but I would like to know how you though of that, from where does it came =)

If you can answer a few more questions I will give you grade A ;)

Thanks a lot for everything you did up to now :)
0
 

Author Comment

by:PIBM
ID: 2705718
Well I'm running into some errors again. I believe this is caused by the DAO thing .. :\
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2706877
Where did it come from...

1 - I had to write a multi threading application. This was a problem, as VB(6) does not support free threading. It does however support some forms of threading, and I had to investigate these.

2 - The problem with VB function calls is that all of them work synchronously. As a result, you cannot, in Native VB, create the situation where process A initiates Process B, then forgets about it, and both processes continue in parallel. At least, not if you want to avoid shelling out separate .exes. Shelling is *WAY* too slow. I wanted an ActiveX solution.
As a result, I had to investigate APIs. CreateThread is one option, but it's too quirky and too much like rocket science. Basically you cannot guarantee that a program using CreateThread will not bomb out with GPFs and similar horrible errors unless you've got a brain the size of a planet.... I quickly abandoned that idea. So the other solution is to use a Timer. I could have used a VB timer, but the API timer is a bit more elegant and it does not require you to introduce a dummy form.

3 DLLs are not usable for multi-threading. Even if you take an apartment threaded idea, each apartment will run in the same thread as the calling process. Again, there are weird and wonderful API solutions to this, but again it requires a brain the size of a planet... So forget that. I then looked at ActiveX .exes for the solution. They worked.

4 This is where I ran into a problem with the threading models supported in VB, especially with regards to global data (variables). Basically, there are two threading models in VB:
a - Thread pool. You can specify as many threads as you wish, but the problem is that every object that is created is assigned a thread "randomly". For sharing global data that is useless. So the only viable option there is to have 1 thread. Now you're OK. Every object that is created uses the *same* global data so it can be shared between the objects. But... *BANG* goes your multi-threading, because *ALL* objects run in the *SAME* thread....
b - Thread per object. Ideal for multi threading. Every object you create runs in its own thread.... but, now you can't share global data. If you have a simple application, this is no problem, as you can code everything into a single class, but if your application gets any more complex, you'll need new classes, and your model will fall apart...

So here's a dilemma.... There are two viable threading models available in my ActiveX .exe, but both have insurmountable problems. One model is useless wrt global data, the other wrt multi threading.

Solution:
5 The ActiveX.exe will only contain a SINGLE object. This object's sole function will be to cater for the multi-threading. Once that is achieved, we'll hand over execution to an Apartment Threaded DLL, which will then take care of any other classes and objects that need to be created, and it will ensure that all these new objects are all created in the *SAME* thread.

The activeX.exe is AWXB04Starter.exe , and the Apartment Threaded DLL is  AWXB01Thread.dll

Finally...
As long as execution remains synchronous, it is very easy for a called function to report back to a calling function. It merely needs to switch off error handling, and raise a user-defined error. The calling function can than handle this "error" and act appropriately.

But in asynchronous execution, that won't work. In actual fact, if you raise an error in the asynchronous bit (that which is called from the TimerProc) your ActiveX.exe will crash.

So how will the threads report back information to the calling application?

6 Introduce a Thread Pool ActiveX.exe (1 thread) that will take care of handling messages between the thread(s) and the calling application.
This ActiveX.exe is AWXB02MSG.exe



I don't know about your DAO errors. If they're unhandled errors they might be causing the problem described before point 6, in which case you can sort that by making sure your error handling is capable of catching all errors.

You can introduce a special message in your messaging .exe to report back fatal errors to the calling application, so that it knows one of its threads has died on it.

You can also introduce messages that are sent from the Calling application to one of the threads.

I don't know about your DAO problems, if they're DAO specific they're outside the scope of this question. I hope you'll sort them.

Hope this helps

Pino
0
 

Author Comment

by:PIBM
ID: 2708754
Thanks a lot, that answer most of my problem. I believe the problem with the DAO driver is when two threads try to write on the database at the same time. Why do I think this is the error - I never get the error with less than 4 thread runnings .. as many thread I have as faster I run into the bug. Not a memory problem because one of the part never write in the database and I can run easily 30 of them at the same time.

I don't know how I'll do to handle the error but I'll see. I can't trace this error in VB since if I run the DLL it won't create new threads.

Also I had a new kind of error - Unknown Bookmark???

I'll check that out tonight. Should I give you your points right now ? :)
0
 

Author Comment

by:PIBM
ID: 2708781
Oh yeah when I create the threads I use a system where the first letter is the type of Form that will be loaded and the following is only for future reference. That give us the possibility to code a lot of things in the same DLL, use the same module for all the functions and stuff like this, that's perfect for this :)

The only thing I can't include somewhere else than on the form is the Database access. Could I create the database access code in the messaging active x, that would use only one connection so there could be no problem with it ?

in the form I use it like this..
form load ...
 dim db as database
 dim rs as recordset

 set db = workspaces(0).opendatabase(...

commandX.click
 set rs = db.openrecordset(SQLCommand)
 ...
 rs.close
 set rs = nothing

form unload
 db.close
 set db = nothing

So if I use the obj of  AWXB02MSG in which I could include a procedure to get the recordset ( like Public Function GetRS(SqlCommand as string) as Recordset ), would that work ?

Just an idea I had :)
0
 

Author Comment

by:PIBM
ID: 2708785
Adjusted points from 100 to 150
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2709625
"messaging active x, that would use only one connection so there could be no problem with it"

Yes, that might work. Well, give it a try!
0
 

Author Comment

by:PIBM
ID: 2714422
That's what I'll do tonight. I should post again tomorrow about any question I might have. If it works perfectly I'll just give you your points =)

And grade A ;)
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

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…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
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…
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…

708 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

14 Experts available now in Live!

Get 1:1 Help Now