(Not logged on) | Register | Log On

You can subscribe to this discussion group using an RSS feed reader. The Joel on Software Discussion Group

A place to discuss Joel on Software

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

Threads in VB6

Does anyone know a safe, stable way of multi-threading a VB6 app.

I am trying to implement an auto-save feature using a timer.  Everything works fine, except there is a slight pause when the auto save is running.  By pause I mean the application seems to lock up for a half a second or so.  This wouldn't be a big deal except that on slower machines it can be as long as 5 seconds. 

In most any other language you would just shoot off a thread to do the autosave. Also you would think that the timer control would run in it's own thread of execution, but it doesn't. 

I was thinking maybe there is a third-party timer control that will do what I need, or does anyone know any techniques that they've used and know to work.
Joshua Send private email
Monday, February 07, 2005
 
 
use my j-- library.

click on my name to download it.

i have a newer version; found bug in socket.

lemon
Lemon Obrien III Send private email
Monday, February 07, 2005
 
 
opps sorry...i realize now your talking about visual basic not visual c
Lemon Obrien III Send private email
Monday, February 07, 2005
 
 
From what little knowledge I have about VB6 and threads, you'll need a third party library. Apparently VB5 used to support threads but was "removed" from VB6.

Why, I have no idea. I already tried using threads for a project here at work and it was just a mess. I ended up using VC++ instead.
Anonymous coward
Monday, February 07, 2005
 
 
You simply can't directly create a thread in VB6 using something like the CreateThread() API.  You could write the code to do this, and it would execute, but the VB runtime is not reentrant, so any code that assigns to a string variable, triggers an error handler, or calls any runtime function would cause a GPF.

VB-only programmers normally do threads by creating out-of-process ActiveX servers.  These get their own thread because of the way processes are implemented.  This is probably not a good solution for an AutoSave feature because processes are heavy, and any callback from the server to your client app would be serialized back onto your main thread anyway.
flying_coder
Monday, February 07, 2005
 
 
>Does anyone know a safe, stable way of multi-threading a VB6 app.
Not possible. The VB6 runtime is not thread safe. If you must do such a thing, write an activeX control or a device driver, but do it in VC.

Bad experiences trying to make a (true) multi-threaded app in VB6. The closest you can get involves that silly apartment threading stuff.
Peter
Monday, February 07, 2005
 
 
In general, VB6 is single threading.  It is possible to instantiate 'stand-alone' exe's, where you 'kick-off' execution of another VB6 program as a Process.  I did this once upon a time to automate 32 different SQL queries, each of which took more than an hour.

I kicked off 32 Processes, each one told what query to run, and then monitored their execution with a 'parent' Process.  But you can't use threading for this, each VB executable MUST be its own task.

You CAN create a primitive Windows Timer with this:

Declare Function SetTimer Lib "user32" (ByVal HWnd As Long, _
  ByVal IDEvent As Long, ByVal mSec As Long, _
  ByVal CallFunc As Long) As Long
 
Declare Function KillTimer Lib "user32" (ByVal HWnd As Long, _
  ByVal TimerID As Long) As Long

Then call it as:

TimerID = SetTimer(0, 0, StartDelay, AddressOf TimerProc)
which means: Call my TimerProc after StartDelay milliseconds

TimerProc should be like:

Public Sub TimerProc(ByVal HWnd As Long, ByVal Msg As Long, _
  ByVal ID As Long, ByVal CurrentTime As Long)

and should call 'KillTimer(0, TimerID)' first thing to shut off the timer (which auto-repeats otherwise).

Or you can use REALBasic, I understand they implemented real threads in that.
AllanL5
Monday, February 07, 2005
 
 
Jason Bock (wrote 'vb6 win32 api tutorial' from wrox press) did a lot of research on this.  Here is his summary.

http://www.jasonbock.net/JB/VbThread.aspx

Also, take a look at active x executables - they might give you what you want.
bw
Monday, February 07, 2005
 
 
I assume you create an "in memory" mirror of the project to snapshot its state while autosaving it.  When the autosave timer fires off, take the snapshot and then commit it to disk using a loop that writes it in chunks with fairly frequent DoEvents calls.  You may want to only call DoEvents every so many "writes" - a little tuning may be needed to determine the right level of responsiveness.

That or use a second (more frequent) timer started by the autosave timer event, which writes a chunk every "tick" until complete.
dilettante
Monday, February 07, 2005
 
 
The DoEvents suggestion is perhaps the easiest one to do. You could take memory snapshot, send that to an ActiveX EXE and forget the whole thing, or use a callback if you have to know when the data is saved.

You have to use some sort of a timer trick in the ActiveX EXE so you have a chance to leave the method before the execution starts. If you don't you haven't gained a thing.

See here for details: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconcreatingtestingexecutable.asp
Thomas Eyde Send private email
Monday, February 07, 2005
 
 
It's really not that hard but you need to know how to partition the work properly. Make the whole project (the main exe) an ActiveX exe and turn the Project Properties Threading "Thread per Object" on. Now when you run the project each public class that gets instantiated from *outside* the project (or via CreateObject) runs in it's own thread.

Now put all of the code that you need to do what you want in one public class and use CreateObject to instantiate it. Use events to communicate with the main thread.

Like the previous poster said, you need to use a timer when calling the method of your public class that will kick off the long process. If you can't find any examples on the internet, email me and I'll send you one.
Wayne Send private email
Monday, February 07, 2005
 
 
vb.Net can
Guillermo Send private email
Monday, February 07, 2005
 
 
"Everything works fine, except there is a slight pause when the auto save is running. "

Do you really *need* multi-threading? Would it not be acceptable to make the auto-save interruptible, whereby it immediately aborts if the user touches the UI? (Winzip achieves this with annoying efficiency!)

Multi-threading for your solution may not be the answer anyway, since you'd need to retro-fit synchronisation logic. I assume the user can modify the document during the save process? Would the auto-save need to lock the entire document for the duration of the process anyway?
Jonathan
Tuesday, February 08, 2005
 
 
It IS possible to multi-thread VB 6, I did it a few years ago. I am out of town, and can not find any sample code. You can search for subclass and multi-threaded and see if there is anything helpful. If you send me an email, I will try to dig up some old code this weekend.
Steven A Bristol Send private email
Tuesday, February 08, 2005
 
 
>>"Do you really *need* multi-threading? Would it not be acceptable to make the auto-save interruptible, whereby it immediately aborts if the user touches the UI? (Winzip achieves this with annoying efficiency!)"

How would I listen for the Key event and then interupt with-out doing so in a seperate thread?
Joshua Send private email
Tuesday, February 08, 2005
 
 
Here's the basic concept, but there's better code to do it:

http://www.freevbcode.com/ShowCode.asp?ID=1287

(Look up SSubTmr6 for a better timer)
Wayne Send private email
Tuesday, February 08, 2005
 
 
Check out http://www.powervb.com/

I believe Matthew Curland, formerly of Microsoft, did quiet a bit of work in this area.  Hopefully, this is of some help to you.
mrdev2u
Wednesday, February 09, 2005
 
 
Jason
Thursday, February 17, 2005
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz