You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
METHOD JOIN(ThreadObjectVar AS InterfaceName, TimeOutVal AS Long) <7>
Waits for the thread referenced by ThreadObjectVar to complete before execution of this thread continues. TimeOutVal specifies the maximum length of time to wait, in MilliSeconds. If TimeOutVal is zero (0), the time to wait is infinite.
Regards,
Bob Zale
Ah, but figuring out "ThreadObjectVar" from
Code:
oTargetFolder.CopyHere(oItem, vOptions)
Please throw us a bone??
3.14159265358979323846264338327950
"Ok, yes... I like pie... um, I meant, pi."
Andrea, if you get the wait methods to work that Bob and others have suggested, please let me know how you did it. Because when I was creating the code, I tried but it appears that the "thread" that you need to wait for is launched by the shell folder system and I could not find an easy way to find the thread handle except enumerating every thread to search for it. That is why I resorted to using the sleep method.
"I haven't lost my mind... its backed up on tape... I think??" :D
Yes, I too resorted the easy way:
I grab the lenght of the file and sleep 1 second per MB.
Code:
IF doZip THEN
DestFile = DIR$ (FilePathStr + destfile TO Udt)
DIR$ CLOSE
IF LEN(DestFile) THEN
incsize = MAK(QUAD, Udt.FileSizeLow , Udt.FileSizeHigh)
IF CreateZipFile( FilePathStr + destfile, FilePathStr + zipfile ) THEN
KILL FilePathStr + destfile
END IF
END IF
END IF
...
SLEEP incsize /1024
Andrea Mariani AS/400 expert Basic programmer @ Home
Adjusting the sleep based on file size is a good idea. Of course HD speed and CPU etc play in to it too. But that is still much better than the static sleep I used.
"I haven't lost my mind... its backed up on tape... I think??" :D
I used the code Gary Beene had modified in post #18 on page 1.
The only thing I did was to add a check after each CopyHere so that it was done before it started to copy the next file.
Code:
----- 'From William Burns and Gary Beene on page 1. -----
'now we start the copy in to the new zip file
vOptions = 20
oTargetFolder.CopyHere(oItem, vOptions)
IF ERR THEN
MSGBOX "Got an Error during the CopyHere method. Error:" & STR$(ERR)
GOTO TerminateZip
END IF
'----- This is the part I added, it waits until the requested file is copied. -----
DO UNTIL oTargetFolder.Items.Count > FileCount 'FileCount starts at 0.
SLEEP 100
LOOP
I also removed the Line with "Sleep 6000", it is not needed any more.
It would be nice to know if anybody has figured out how to use JOIN, as suggested.
It would be nice to know if anybody has figured out how to use JOIN, as suggested.
This is impossible. Nobody, not even Microsoft, can currently wait on the compression thread to exit.
See below for where MS's code creates the thread (this is from current Win10, but this part of the code hasn't changed since XP). If you check up on SHCreateThread on MSDN, you'll see it returns neither the thread handle nor its id, which means threre's no easy way for anybody to wait for it. This is fine for explorer since that's generally always running, but anybody else has to has to hack around it and use some other metric to determine when its finished.
(Sorry for the big picture, sizes other than fullsize don't seem to work). I seem to remember, though its been years since I looked, the low level interfaces (IStream, IStorage) would compress as they went file-by-file rather than all at once, but up to Win7 had a bug where they tried to open a non-existant temp file and so always failed.
Non logged in people can find the picture here
Can someone help and do the trick and replace "SLEEP" with "WaitForSingleObject" in the example or is there another solution?
PB SLEEP and WinAPI WaitForSingleObject() do different things. You cannot "replace" either with the other. (Which would certainly make it a 'trick' !)
Sometimes you see both here and in the PB help "SLEEP" being used at the start of additional threads of execution. SLEEP as used in these cases can be considered a "cheap and dirty" way to accomplish "waiting for initialization" but the better (IMO) way to do that is to use a Windows event and suspend the calling thread using WFSO until the thread function has explicitly signaled initialization is complete.
There really are two ways to hold execution pending "something" being completed in another thread of execution (which can include threads owned by another process):
Method One can be expressed in pseudo-code thus:
Code:
DO
Check something to see if "other thing is done"
This can be testing a global variable or maybe a disk file
IF Thing IS DONE
EXIT DO
ELSE ' it's NOT done yet
delay and retry later... typically using SLEEP
SLEEP some anpount of number
END IF
LOOP
' Program resumes knowing "thing is done."
Method Two is the one I suggest; it's a little simpler in pseudo-code AND more efficiently uses system resources: .
:
Code:
' do things here
'Wait until "other thing is done"
iret = WaitForSingleObject (handle_to_event, timeout_period)
' program resumes knowing "thing is done."
A whole bunch of my demos in the source code forum show 'Method Two' in action.
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment