Is FileSystemObject a blocking call?

JMongi

Active member
Local time
Yesterday, 19:27
Joined
Jan 6, 2021
Messages
802
I can't seem to find a definitive answer.

Related to this would be if anyone has a list of blocking/non-blocking calls. You might also describe it as synchronous/asynchronous.

For example, a shell object method is fired off as an asynchrounous call, passing along its info the the shell and then moving along its way though the script not caring if that process is finished or not.

Most VBA is sychronous (as I understand it), meaning one command/code block will resolve before moving to the next.

I'll keep looking but thought I would post here.
 
I don't have any reference, but if you're using VBA to create a FSO object and then use its methods, then my guess is you're also working in synchronous mode with FSO at that time.
 
I will explain the real world scenario as well.

In a few different sample scripts copying FE files there was code added to "wait/sleep" until the file copy was complete before executing a run command to launch the db.
The reason given was to ensure that Access wasn't trying to launch a file that was in the middle of being copied over.

I give this example because synchrounous = will not proceed to step 2 until step 1 is complete. However, the defenition of "Step 1 is complete" may not be so simple.

Code:
Dim fso as Object
Dim source as String, target as String
fso = CreateObject("Scripting.FileSystemObject")
fso.CopyFile source, target, true

Is fso.Copy file considered complete when the underlying stack call is passed to the execute engine (pardon my jumble of programmer speak if I'm not apply terminology correctly) whether the files have been actually copied or not? Or is it not complete until the the files are residing in the target location and the fso.CopyFile method is notified in some internal way that all files have been copied.

@theDBguy - I agree, just trying to look for some actual documentation or something.
 
Again, this is all pure speculation. When you execute the Copy method of the FSO object, my guess is it may be invoking an OS call, since it has to do with the file structure. If so, it may be this call to the OS process that makes it asynchronous.

I think that example might be misleading. If you believe VBA is synchronous, then check out the VBA's FileCopy statement. It should help prove if the process of copying a file is done within Access or outside of it.

I think...
 
"...then check out the VBA's FileCopy statement..."
Sorry that I don't understand what you mean by this?
 
I mean, I've read that file already and I couldn't find any information on whether it's methods were synchronous or not or what is going on under the hood that might help me understand when it considers it to be complete for moving to the next line of code.
 
I mean, I've read that file already and I couldn't find any information on whether it's methods were synchronous or not or what is going on under the hood that might help me understand when it considers it to be complete for moving to the next line of code.
Yeah, no, I don't think so either (that it will elaborate on how it does it). All I was saying is based on your statement that if VBA is synchronous and you execute a FileCopy statement, then you shouldn't have to wait for it to finish before moving on. In other words, doing something like this shouldn't be necessary.
Code:
MsgBox "About to copy a file..."
FileCopy Source, Destination
Pause or Wait
MsgBox "All done!"
Meaning, the Pause or Wait line shouldn't be necessary. (If you do try to test it, try to use a large file to make sure it takes a while to copy - you may have a fast computer.)

Hope that makes sense...
 
Yeah, if I get an opportunity to test it, I will and post back. But, I was hoping someone more knowledgable of the underbelly of things might illuminate matters! :)

For now, my copying is so trivially fast that a very small (milliseconds) delay should be all that is required to avoid errors. I also, might just figure out a way to programmatically check for the file copy completion just because!
 
In general, Access VBA code is synchronous though there HAVE been some rather complex attempts to force async operation, usually involving API calls. I am inclined to say that in the absence of an API-based FORK call that all FSO references are synchronous. Note that if you had a SHELL script that the SHELL command DOES create a potentially asynchronous situation.

While application objects involve creating separate processes, nonetheless the combination of Access and an app object such as Excel will remain synchronous for the most part unless you have somehow triggered timers in both Access and Excel. The reason is that app objects open a local network channel (through the LOOPBACK device) and the app object gets its commands from that connection.
 
Thanks for the info @The_Doc_Man, I figured you would have some knowledge of the underpinnings of everything!
Even though the real world timing is trivially small, I ended up setting up check code to count the number of files in the source and destination folders and make sure they match. That should protect things no matter the situation.

Code:
Sub FileXfer ()        'Transfer new files from shared network location to local user
sModuleName = "FileXfer"

'Set the string paths
Dim sSource, sDestination
sSource = Left(cServerPath,Len(cServerPath)-1)
sDestination = Left(sLocalFE,Len(sLocalFE)-1)

'Delete current files and copy new ones
oFSO.DeleteFolder sDestination
oFSO.CopyFolder sSource, sDestination

'Check if files copied
Dim oSource, oDestination
Set oSource = oFSO.GetFolder(sSource)
Set oDestination = oFSO.GetFolder(sDestination)

Do Until oDestination.Files.Count = oSource.Files.Count
    Wscript.Sleep(1)
Loop

Call ErrHandler (sModuleName)
End Sub

Note: This is VBScript, not VBA so the syntax and variable definitions are slightly different. Also, I define sModuleName, cServerPath, sLocalFE and oFSO in other parts of the script.
 
Ah, VBA script. NOTE that there ARE some differences in environment. It would be easier in VBA script to create an async operation. The way you are using the FSO calls, I don't see any hints of async operation, but I should point out that your method leaves you at risk if either folder is actively being shared at the moment. There is no guarantee that the file counts will match in your sleep loop.

It should be enough to verify that the files you just copied exist in both places. You might also check whether the file sizes are the same and then not bother with the sleep loop.
 
Can you elaborate a bit? The destination is a local folders on each user's computer. The source is a network share hidden using the "$" switch. So, theoretically someone could be in there but it is unlikely. The file exists check makes sense but I guess I'm missing the VBScript knowledge to check for file existence for all files without specifically listing those files. It's probably a method close to what I'm doing now I suppose. I'll look into it.
 
OK, I looked at that wrong before. You are doing a FOLDER copy. It should be possible to write a loop to step through the source files and do a test on the corresponding destination files. There are FSO methods that would separate the path and name from a source element and allow you to tack the source file name & type onto the destination path, then compare properties in a loop. The other way to do that would perhaps be to do a DIR command using > to redirect output to a file. Create directory listings for both files and compare them. You might have to play with the DIR switches / options to limit the output to something you could compare using the FILE COMPARE scripting option. Note that if there are child folders in either folder (source OR destination) things get more complex.
 
Interesting

At the moment I am dealing with a process that makes a restive API call in the middle, and I wonder with this call becomes asynchronous . Part of the process uses the result of the restive API call, but I am wondering whether they might use the result of an earlier API call, if the current one hasn't completed. I am not sure if I need a wait or not. See pseudocode below

Code:
dostuff
dostuff
call sub to make API call
wait for API call to finish?? do I need this?
dostuff which depends on the API call having completed.
dostuff
dostuff
 
I'm sure theDoc will have a lot more technical detail, but, a couple of questions of my own:
1. Can you wait until the previous API call is completed to initiate your 2nd API call? Is there a way to assure that programatically?
2. Some calls have returns. Is there a way to monitor the return?
3. If there is no return, is there another event/value/etc that can be used as an indicator of call completion?
 
When calling an API function, it most commonly points to a .DLL file, which contains subroutines and/or functions. The only way to know if anything of an async nature opens up is to carefully read any documentation - on a per-subroutine basis. In GENERAL (and certainly subject to the whims of the MS developer team), dynamic link libraries are NOT written to be asynchronous. If the sub description doesn't talk about async operations, then there will be none. For an example that has async implications, look at the description of what happens with PASSTHRU queries.

If there is a return, it will be one of two common methods.
1. The call is to a FUNCTION - in which case use syntax RESULT = FUNCTIONNAME(arguments) and then just look at RESULT.
2. The call is to a SUB that has a BY REF argument. IF (and only if) that argument represents a status, test the argument after the call.

It is HIGHLY unlikely that any API call or library call will use side-effects - i.e. a global value return. If they return something, look at it.

As an example from something you see quite often, look at the FORM_OPEN call which includes a BY REF CANCEL AS INTEGER argument. YOU return the -1 (=TRUE) argument to trigger the cancellation of the event. MS will use that method or a status return from a function, which is in the opposite direction from the CANCEL As Integer stuff we see in cancellable events.

The ONLY oddball I've personally seen is if you use some of the WinSock routines to do network communications, you test the status to see if it worked or not, but have to use a separate call to get details of the previous operation because the working data structure is inside of a class module and you have to do things like PROPERTY GET operations or even actual function calls to get status codes.
 
I'm sure theDoc will have a lot more technical detail, but, a couple of questions of my own:
1. Can you wait until the previous API call is completed to initiate your 2nd API call? Is there a way to assure that programatically?
2. Some calls have returns. Is there a way to monitor the return?
3. If there is no return, is there another event/value/etc that can be used as an indicator of call completion?

was this directed to me?

The system is making regular API calls. Occasionally we see unexpected errors. There's only one API call per transaction, but if the API call result hadn't been received by the time the next process runs, that would most likely explain the problem. I can find a way of building in a wait, (set a flag before making the API Call and clearing it when the call finishes) but I wasn't sure whether I actually needed to, or whether the occasional error might be caused by a different issue.
 
@gemma-the-husky
Yes, that was at you ;)
Depending on how often "occasional error" occurs, that seems like a relatively time efficient way to test if your suspicion is correct. I would guess without a much more deep dive into the specifics of your code, which API calls are made and everything else, it would very difficult to give a definitive answer. That's why I think it would be the most time-efficient to make the code changes you mention and simply see if the error goes away.
 

Users who are viewing this thread

Back
Top Bottom