Hi Christof,
It's been a while since I've looked at this madness <g>...
Yes, you're right - I forgot that ASP holds the DLL captive on a thread. But it's really unreliable because there an instance of the DLL tied to each thread in ASP.
If you run your test from a couple of separate browser instances (ASP does something with Keep alives and trying to tie the client to the same thread if load is light) you'll see that from time to time the tables are forced open again. I take this to mean that a new thread is firing up and a new instance of the VFP runtime is getting bound to it.
You can see that happening if you ammend the code with:
FUNCTION TableTest
IF !USED("WebCounters")
USE WebCounters IN 0
RETURN "Table openeded..." + TRANSFORM(Application.ThreadId)
ENDIF
SELECT WebCounters
RETURN "Table already open..." + TRANSFORM(Application.ThreadId)
ENDFUNC
and you'll see the thread number bounce around. As long as the thread was previously hit the table is already open. Hit a new thread and the table is opened again. So each instance of VFP is managed per thread.
Of course if you use a Session object things always open and close which is unfortunately the default recommendation Microsoft makes <g>.
+++ Rick ---
>Hi Rick,
>
>>No, this isn't right... Tables close when the object is destroyed in all
>>situations. Even if you're not using a Session object.
>
>I guess my comparison to a desktop application wasn't the best one <g> COM objects are created in an instance of VFP. This instance is bound to the lifetime of all objects instantiated in that instance. If the last object is destroyed, the instance is shut down and all tables are closed. As long as there's one object still alive, the instance remains loaded and tables stay open.
>
>>Try this in an MTDLL:
>
>Compiled it to test.test. What I meant is the following. Even though o1 is released in between, the table remains open because o2 keeps the instance in memory.
>
>o1 = CreateObject("test.test")
>? o1.TableTest()
>o2 = CreateObject("test.test")
>o1 = null
>o1 = CreateObject("test.test")
>? o1.TableTest()
>
>Of course, this is a simplified scenario, because VFP as a host doesn't load the MTDLL into multiple threads or does weird things with caching DLLs as ASP does.
>
>>Well, the point is moot since tables can't stay open across calls. There's no point in closing tables if you're using MTDLLs from ASP/ASP.NET since they don't persist.
>
>What are you doing differently than I am? I copied the test.dll created from your code into \inetpub\scripts and registered it. I also created a webcounters.dbf file in \Windows\System32, because that's where DLL tries to open the file. Then I create the following test.ASP:
>
><%
> Set oRef = createobject("test.test")
> Response.Write( oRef.TableTest() )
> Set oRef = Nothing
>
>
>The first time I call the page I get "Opened table". Then I hit F5 and get "Table already open". This is on Windows XP SP2 with ASP being pretty much in the default configuration.
>