tags:

views:

1239

answers:

6

Hi, I am testing an application that checks if a file exists across a network. In my testing, I am purposefully pulling the network plug so the file will not be found. The problem is this causes my app to go unresponsive for at least 15 seconds. I have used both the FileExists() and GetAttr() functions in VB6. Does anyone know how to fix this problem? (No, I can't stop using VB6)

Thanks, Charlie

A: 

I'm not sure you can handle this much more gracefully - if the network is having problems it can take a while for timeouts to indicate that the problem is severe enough that things aren't working.

If VB6 supports threading (I honestly don't recall) you could spin the file open into a background thread, and have the UI allow the user to cancel it (or perform other operations if that makes sense), but that introduces a pretty significant amount of additional complexity.

Michael Burr
A: 

VB is inherently single threaded, but you can divert work to a COM component to do an asynchronous file check and flag an event when it is done. This way the UI thread stays at responsive at least. Trouble is - this is all theory, I don't know such a component.

But wait! Google just turned up this: Visual Basic 6 Asynchronous File I/O Using the .NET Framework. Does that help, maybe?

Also, they have something similar over at CodeProject: Asynchronous processing - Basics and a walkthrough with VB6/ VB.NET

Tomalak
A: 

VB6 has some networking functions that can test to see if the network is connected. You should be able to add in under 'References' the 'NetCon 1.0 Type Library'. This adds for you the NETCONLib. Once implemented, you should be able to test for network connectivity first, then test for the FileExists and GetAttr.

Let me know if this helps!

JFV
A: 

I agree with Will. Something like this is simple to handle with Script.FileSystemObject:

Dim objFSO As New FileSystemObject 
If objFSO.FileExists("C:\path\to\your_file.txt") Then
    ' Do some stuff with the file
Else
    ' File isn't here...be nice to the user.
EndIf
Bullines
objFSO.FileExists won't return until the timeouts kick in that he wants to avoid in the first place.
Tomalak
A: 

Accessing files over a network can cause these hangs.

It's been a while, but I remember multi-threading in VB6 being relatively painful to implement. A quick solution would be to have a small .exe (perhaps also coded in VB) that can handle this. You could use DDE for inter-app communication or the ever so easy but kludgey file-based pipe, by which I mean a file that both apps will mutually read/write to handle inter-app communication. Of course, using file-based pipes, depending on the details of this scenario, may simply exaggerate the File I/O lag.

If there's a reasonable degree with which you can predict where the user will be selecting files from, you may consider preemptively caching a directory listing and reading that rather than the file directly - assuming the directory contents aren't expected to change frequently. Note: getting a directory listing over a network will cause the same lag issues as individual file I/O over a network. Keep that in mind.

coderGeek
+4  A: 

Unfortunately, VB doesn't make this easy, but luckily the Win32 API does, and it's quite simple to call Win32 functions from within VB.

For the LAN/WAN, you can use a combination of the following Win32 API calls to tell you whether the remote connection exists without having to deal with a network time-out:

Private Declare Function WNetGetConnection Lib "mpr.dll" Alias _
    "WNetGetConnectionA" (ByVal lpszLocalName As String, _
    ByVal lpszRemoteName As String, ByRef cbRemoteName As Long) As Long

Private Declare Function PathIsNetworkPath Lib "shlwapi.dll" Alias _
    "PathIsNetworkPathA" (ByVal pszPath As String) As Long

Private Declare Function PathIsUNC Lib "shlwapi.dll" Alias "PathIsUNCA" _
    (ByVal pszPath As String) As Long

For the Internet, you can use the Win32 API call:

Private Declare Function InternetGetConnectedState Lib "wininet.dll" _
    (ByRef lpdwFlags As Long, ByVal dwReserved As Long) As Long

Const INTERNET_CONNECTION_MODEM = 1
Const INTERNET_CONNECTION_LAN = 2
Const INTERNET_CONNECTION_PROXY = 4
Const INTERNET_CONNECTION_MODEM_BUSY = 8

This VB site has more discussion on path oriented functions you can call in the Win32 API through VB.

RoadWarrior