I've got a little problem like the chicken and the egg.
A program responsable for moving files between servers, sending email and
printing over several locations uses for every job a new thread. These
threads are limited to 5 threads at the same time. Because sometimes 5333
errors occurd I now use dynlock() before I start the first job and
dynUnlock() when all jobs are ready. The 5333 errors disappeared, but while
the dynlock is active the main thread still displays strings and aDirs are
filled in search of more jobs to do. These strings and arrays are eating
all dynamic memory.
So now I've two options:
1 Don't use dynlock and the program dies with 5333 cause ptr's in nonactive
threads are eaten by the GC
2 Use dynlock and the program dies with out of dynamic memory when moving a
large file
Does anybody know a workaround, It's driving me crazy.
TIA
Rens
Dynlock shouldn't be necessary - it means something is wrong with your code.
Perhaps if you explain a little more about what goes into and out of each
thread we might be able to help. AFAIK if each thread is fully self
contained then you should have any 5333's.
In the meantime, raise the primary allocation at runtime as per the docs.
Geoff
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in
message news:01c21d1c$83940180$0d320a0a@User...
As far as I give PTR's to my threads, I think they are all static, But as
you can see in the email-sample below I use functions in the threads and
they have dynamic locals.
The main basic of tyhe program is a mainwindow with a TimerEvent every
second. This event updates some counters and fires a mainloop or other
processes if there time is reached. the mainloop can run only ones at the
time. In this mainloop I fill an array of several databases with contains
directories on several drives(servers). There can be max. 1 email, 1
printjob, 1 zipjob and 3 movejobs at the same time. So if the database said
that the a directory contains movejobs and there are less than 3 movejobs
busy The program does a Directory(). If the ALen(aDir) > 0 the program does
all kind of checkes like 'open exclusive' and then fires the code below.
The pointers missing I mentioned, are trough the whole program. Objects in
the mainthread or in write2email function for example just disappear and
become 5333 when used. With dynlock this doesn't happen.
I must be doing something.... , but after 3 months searching 5333 I'm
getting loco. {;-))
Tia for looking
Rens
Part OF the MainProgram:
oThr1:=MemAlloc(_SizeOf(_SDThreadInfo))
IF oThr1==NULL_PTR
SELF:ToErrorListbox(Str(aLine[POS_MOVE_LINENUM])+aLine[POS_ACTION]+"
"+"Memory allocation failed")
ELSE
SysObject():liMoveThreadsActive+=1
SysObject():SetFileInUse(cDirFrom+"\"+aDir[nI,1],aDir[Ni,F_SIZE],cDirTo)
oThr1.hWnd:=SELF:handle()
oThr1.Kind:=KIND_MOVE
oThr1.InFile:=StringAlloc(cDirFrom+"\"+aDir[nI,1]+CHR(0))
oThr1.OutFile:=StringAlloc(cDirTo+"\"+aDir[nI,1]+CHR(0))
BEGIN SEQUENCE
SELF:ToLogFile("CreateVOThread "+cDirFrom+"\"+aDir[nI,1])
SELF:LockDynMem()
hThread:=CreateVOThread(NULL,0,@OnStartThreadFileMove(),oThr1,0,@dwID)
SELF:ToLogFile("CreateVOThread Ready "+cDirFrom+"\"+aDir[nI,1])
RECOVER
oThr1.dwSucces:=THREAD_CREATION_FAILED
PostMessage(SELF:handle(),SysObject():RegWinMsg,DWORD(_CAST,oThr1),MemFree_F
ileThread)
SELF:ToErrorListbox(Str(aLine[POS_MOVE_LINENUM])+aLine[POS_ACTION]+"
"+"BEGIN SEQUENCE")
END
IF hThread==NULL
oThr1.dwSucces:=THREAD_CREATION_FAILED
PostMessage(SELF:handle(),SysObject():RegWinMsg,DWORD(_CAST,oThr1),MemFree_F
ileThread)
END
END
FUNCTION OnStartThreadFileMove(lpVoid AS PTR) AS DWORD PASCAL
LOCAL sThreadInfo AS _SDThreadInfo
LOCAL OpStruct IS _winSHFileOpStruct
sThreadInfo:=lpVoid
IF IsPtr(sThreadInfo.hWnd)
OpStruct.hWnd:=sThreadInfo.hWnd
OpStruct.wFunc:=FO_MOVE
OpStruct.pFrom:=sThreadInfo.InFile
OpStruct.pTo:=sThreadInfo.OutFile
OpStruct.fFlags:=_OR(FOF_NOCONFIRMATION,FOF_NOERRORUI)
sThreadInfo.dwSucces:=SHFileOperation(@OpStruct)
END
PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg,DWORD(_CAST,lpVoid),MemF
ree_FileThread)
ExitVOThread(0)
RETURN 0
In case of an email The thread starts with a call to a function
FUNCTION OnStartThreadFile2Email(lpVoid AS PTR) AS DWORD PASCAL
LOCAL sThreadInfo AS _SDThreadInfo
LOCAL OpStruct IS _winSHFileOpStruct
sThreadInfo:=lpVoid
sThreadInfo.dwSucces:=WriteFile2Email(Psz2String(sThreadInfo.EmailAddress),
Psz2String(sThreadInfo.InFile),Psz2String(sThreadInfo.Subject))
IF sThreadInfo.dwSucces==NO_ERROR
IF sThreadInfo.lValidOutDir
OpStruct.hWnd:=sThreadInfo.hWnd
OpStruct.wFunc:=FO_MOVE
OpStruct.pFrom:=sThreadInfo.InFile
OpStruct.pTo:=sThreadInfo.OutFile
OpStruct.fFlags:=_OR(FOF_NOCONFIRMATION,FOF_NOERRORUI)
sThreadInfo.dwSucces:=SHFileOperation(@OpStruct)
ELSE
IF !FErase(sThreadInfo.InFile)
sThreadInfo.dwSucces:=ERROR_ERASE_EMAIL_ORIGIN
END
END
END
PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg,DWORD(_CAST,lpVoid),MemF
ree_FileThread)
ExitVOThread(0)
RETURN 0
FUNCTION WriteFile2Email(cEmailTo AS STRING,cFile AS STRING,cSubject AS
STRING) AS DWORD PASCAL
LOCAL dwResult AS DWORD
LOCAL oEmail AS cEmail
LOCAL oSmtp AS PB_SMTP
LOCAL cData AS STRING
LOCAL cLRec AS STRING
LOCAL hFile AS PTR
LOCAL lEOF AS LOGIC
LOCAL nBytes AS DWORD
LOCAL oFS AS FileSpec
oFS:=FileSpec{cFile}
IF SLen(AllTrim(cSubject))>0
cSubject:=" ("+cSubject+")"
END
DO CASE
CASE oFS:Size>2000000 // limit max email
dwResult:=ERROR_ATTACHMENT_2_BIG
CASE oFS:Size>30000 // Limit standaard groupwise6 viewer
oEmail:=cEmail{}
oEmail:Boundary:="----------TheGardenSpecialistBoundary"
oEmail:AttachmentFileList:=cFile
oEmail:FromAddress:="F...@thegardenspecialist.com"
oEmail:FromName:="FT1"
oEmail:MailBody:="This email is sent as an attachment due to a size limit
of 30KB";
+crlf+"The Email is found as: "+oFS:FileName+oFS:Extension+crlf
oEmail:DestList:=cEmailTo
oFS:=FileSpec{cFile}
oEmail:Subject:="File: "+oFS:FileName+oFS:Extension+cSubject
oSmtp:=PB_SMTP{oEmail,"The Garden Specialist mailer V1.00"}
oSMTP:RemoteHost:="10.10.10.35"
osmtp:Timeout:=5000
IF oSmtp:SendMail()
dwresult:=NO_ERROR
ELSE
dwResult:=ERROR_ATTACHMENT_2_FILE
END
oSmtp:Disconnect()
oSmtp:Close()
oFS:=NULL_OBJECT
oSMTP:Email:=NULL_OBJECT
oEmail:=NULL_OBJECT
OTHERWISE
hFile:=FOpen(cFile,FO_READ)
IF hFile<>F_Error
lEOF:=FALSE
cData:=""
DO WHILE !lEOF
cLrec := Space(10000)
nBytes := FRead(hFile, @cLrec, 10000)
IF nBytes < 10000
lEof := .T.
END
cData+=Left(cLrec,nBytes)
END
END
FClose(hFile)
oEmail:=cEmail{}
oEmail:FromAddress:="F...@thegardenspecialist.com"
oEmail:FromName:="FT1"
oEmail:MailBody:="This is a conversion to email from file:
"+oFS:FileName+oFS:Extension+crlf+crlf+cData
oEmail:Subject:="File: "+oFS:FileName+oFS:Extension+cSubject
oEmail:DestList:=cEmailTo
oSmtp:=PB_SMTP{oEmail,"The Garden Specialist mailer V1.00"}
oSMTP:RemoteHost:="10.10.10.35"
osmtp:Timeout:=5000
IF oSmtp:SendMail()
dwResult:=NO_ERROR
ELSE
dwResult:=FILE_2_EMAIL_FAILURE
END
oSmtp:Email:=NULL_OBJECT
oSmtp:Disconnect()
oSmtp:Close()
oEmail:=NULL_OBJECT
oSmtp:=NULL_OBJECT
END
RETURN dwResult
STRUCT _SDThreadInfo
MEMBER hWnd AS PTR // reply back to
MEMBER Kind AS DWORD // soort email,printer,enz
MEMBER InFile AS PSZ
MEMBER OutFile AS PSZ
MEMBER OutDir1 AS PSZ
MEMBER OutDir2 AS PSZ
MEMBER Printer AS PSZ
MEMBER Zip AS PSZ
MEMBER EmailAddress AS PSZ
MEMBER Naam AS PSZ
MEMBER Password AS PSZ
MEMBER dwSucces AS DWORD
MEMBER lValidOutDir AS LOGIC
MEMBER Subject AS PSZ
Without getting into the structure of your too much, I think I see the area
I would be worried about. Whilst you pass ptr's around the threads (and yes
they are static), guess what they point to? Objects.... which move. So you
send a pointer all right but the GC can move the object in the other thread
so what is the ptr now looking at? When you use DynLock you are preventing
the GC from moving the objects so the ptr's stay meaningful.
There are three solutions you can try:
1) Up the primary dyn mem loaded at startup and keep doing what you are
doing.
2) Make the objects being passed as static objects in the primary thread.
You can now pass pointers to these and the GC will not interfere. But you
also chew up static memory something fierce <g>. You still run the risk of
keeping lots a mem in use.
3) Don't pass anything! Or maybe just a structure with some info. My
point would be that you use the primary thread to "manage" and control the
activities necessary but it doesn't do any of the actions. For instance,
your mailing thread. Don't create the necessary objects in the primary
thread - create them in the thread. Pass file names or other data if
necessary but do so in a structure. But the objects you are using can then
be created and destroyed in the thread thus making it threadsafe.
HTH
Geoff
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in
message news:01c21db0$508f1880$0d320a0a@User...
I think (at least I think I do) that I did just that you mentioned in item
3. As you can see in the sample-source I provided, I always create a
structure with static pointers to strings etc. See STRUCT _SDThreadInfo at
the bottom.
On CreateVoThread I give this structure to the new thread. In the
thread-start-function I use objects and functions.
The last command in the thread is a postmessage to the mainthread to clean
up the structure.
I noticed just now that I use the wrong hongarion notation from an old
experiment. The oThr1 should be sThr1, cause it's a structure and not an
object I'm passing.
If you see moving objects, please mention there name. I'll break there feet
and they will stay at place.<g>
Rens
For me to comment further on this I'd need to run the app and try following
the objects life cycle. For example, I see some asynchronous operations
initiated just before you close the thread. Could it be that this is part of
the problem? You have a number method calls that "appear" to call out to GUI
style objects and this is where I think your trouble comes from. But as I
said, we'd need to see the whole operation before commenting sensibly. When
you initiate GUI output you need to make sure that thread is not terminated
unexpectedly without dealing with these objects. Sometimes the primary
thread can close a secondary thread without consultation. If that thread has
dynamic objects then you are in trouble. As per the manual <g>.
In your threads, could you use text output or file output and manage these
files (ie displayed etc) from the primary thread? Again, because we can
only see a part of your application, how are you managing SysObject()?
Whilst I am a great fan of this tool (and Paul Piko is not <g>), I certainly
have worries about using it across thread boundaries. maybe its completely
safe - I don't know.
Geoff
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in
message news:01c21dd2$147a6b20$0d320a0a@User...
Somewhere there's a lightbulb that goes on. <g>
Do you mean that the pointers to the mainwindow and the sysobject can be
obsolete at the moment I close the thread and I post a message back to the
mainwindow, like in PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg
...?
What about Api-Calls like messagebox() where I use Self:Handle() or is this
behaviour only in multithreading?
Do I have to move the mainwindow to oldspace to be able to use it's ptr in
thread's or is there another workaround to reach the mainwindow?
After the lights went on, it's getting foggy. I'm sure it's not the
alcohol.<g>
Rens
> Somewhere there's a lightbulb that goes on. <g>
good, its still darak here <g>
> Do you mean that the pointers to the mainwindow and the sysobject can be
> obsolete at the moment I close the thread and I post a message back to the
> mainwindow, like in PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg
Of course! You see, you ARE referring to dynamic memory objects across the
thread boundary. This is a serious no-no. Have you read CA's white paper on
the subject? Its on your CD. Ginny Caughey also wrote a companion paper on
the subject. Read both - they highlight the same material but have different
ways of presenting the concepts.
> What about Api-Calls like messagebox() where I use Self:Handle() or is
this
> behaviour only in multithreading?
Self:Handle() is fine because you are passing this to a modal entity and the
GC cannot fire before MessageBox() is shown. Were you to save self:handle()
to a ptr, do some further processing (that caused the GC to fire) and then
passed the pointer to MessageBox(), then you are in deep do-do.
> Do I have to move the mainwindow to oldspace to be able to use it's ptr in
> thread's or is there another workaround to reach the mainwindow?
Try it! I have never seen anyone discuss this as an option. I know Meinhard
often comments on this subject and as yet I haven't seen him discuss this
but all theory says it should be fine <g>. Try it and let us know. Maybe
this is the "safe" way to deal with GUI objects in the primary thread but
certainly, the reverse would not be true because of the potential to close
the secondary thread from the primary thread.
Geoff
> > Do I have to move the mainwindow to oldspace to be able to use it's ptr in
> > thread's or is there another workaround to reach the mainwindow?
>
> Try it! I have never seen anyone discuss this as an option. I know Meinhard
> often comments on this subject and as yet I haven't seen him discuss this
> but all theory says it should be fine <g>. Try it and let us know. Maybe
> this is the "safe" way to deal with GUI objects in the primary thread but
> certainly, the reverse would not be true because of the potential to close
> the secondary thread from the primary thread.
I probably shouldn't comment since I haven't read the whole thread, but I
recommend using PostMessage to a window's handle (or to a control's handle) as
the only safe means of comminication from a secondary thread to a GUI element.
The problem wtih GUIs and threading as I understand it is that the underlying
Windows functions simply aren't thread-safe. Using PostMessage is safe, however,
because Windows guarantees that messages are only delivered to active threads.
Although the VO GC can exacerbate threading problems, languages without a GC (or
where the GC runs on a separate thread and can stop all other threads from
running while it acts) still have this issue. In .Net for example, you'd invoke
a delegate (a callback basically) running on the GUI thread to do work on the
GUI rather than doing something on a GUI from a worker thread directly.
Ginny
Sitting in the dark? With the lights on and even after a good night sleep,
I'm getting even more confused with this info. <g>
I've read the white paper on the subject, but (maybe because of my poor
english) I'm missing the link somewhere.
So back to the answers, if I pass the pointer to the Mainwindow in a
structure to the second thread than the GC can change the original ptr by
moving the window through memory. The pointer in the structure is obsolete
now. Geoff, you see this as a dangerous situation while Ginny, you say I
should use postmessage(ToTheMaybeObsoleteWindowPointer,......
If I understood correctly, this is really a dangerous situation waiting for
5333's to fire. But how can I send the mailman with a reply if the location
I have to send to just keeps disappearing. IOW where should the postmessage
go to? Is there anything stable to find?
How about the fact that I created the structure in the main-thread in
static memory, shouldn't the GC update the pointer here if it replaces the
window through memory. Is the second thread not looking at the same pointer
as well.
Ginny, please read my first post also, I've got a huge dilemma with this.
Thanks,
Rens
I agree with your comments on PostMessage. But what Rens is doing is setting
up a main window in the primary thread and passing a pointer to it in the
secondary threads. From there he executes methods on the GUI window in the
primary thread. This is what I consider dangerous. And he gets 5333's to
prove it <g>.
Your comment on .net approaches is interesting. I think the delegate idea is
good advice and it is basically the way I do it with VO. All my GUI is in
the primary thread and messages go forward from the threads to the main
thread but these only carry static data (usually status messages for
display). I have a "client" which is sitting waiting for these messages in
order to display them or initiate some other action.
Geoff
"Ginny Caughey" <ginny....@wasteworks.com> wrote in message
news:afgf47$e0mom$1...@ID-144704.news.dfncis.de...
Reading your post to Ginny, I think that you think something now that is
_NOT_ there.
Please explain if I'm wrong, but I think I do:
In my window:methods I decide if a job has to be done.
If so I create a structure in static memory with information like
window:handle(), filename etc.
This pointer to this structure I pass to a new thread.
In this structure is a dword that contains the result like NO_Error and is
filled in by the new thread.
If the thread is ready, it sends a postmessage to this mainwindow:handle()
and the pointer to the structure.
In the main thread I examine the result in the structure and to remove the
structure out of memory after finishing displaying the result.
Rens
> I agree with your comments on PostMessage. But what Rens is doing is setting
> up a main window in the primary thread and passing a pointer to it in the
> secondary threads. From there he executes methods on the GUI window in the
> primary thread. This is what I consider dangerous. And he gets 5333's to
> prove it <g>.
Yes I agree.
> Your comment on .net approaches is interesting. I think the delegate idea is
> good advice and it is basically the way I do it with VO. All my GUI is in
> the primary thread and messages go forward from the threads to the main
> thread but these only carry static data (usually status messages for
> display). I have a "client" which is sitting waiting for these messages in
> order to display them or initiate some other action.
That's the key. Anything, ANYTHING, that touches the GUI should be running in
the same thread as the GUI.
Ginny
Forget about any pointers to windows or controls. All you need is the HANDLE.
The handle won't change, the GC won't move it, and you can use it from worker
threads. Make up a custom Windows message, like WM_USER+100 or whatever. Then
call PostMessage, passing in the handle of the window you want to receive the
message. In that window's Dispatch, look for WM_USER+100, and if you get it,
that means no error, or whatever you choose. You can also use the WParam and
LParam parameters of the message to convey information that is meaningful to
both threads.
HTH,
Ginny
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in message
news:01c21e7b$8cbcf680$0d320a0a@User...
Ginny has answered it first. As she points out, the handle to a window
(which comes from an API call) is about the only safe thing to throw around
between threads. You might then be passing pointers to structures (and
that's ok too...) but if the structure itself contains pointers to dynamic
objects then you are sunk. Set up static buffers by all means and use
pointers to these to carry strings or arrays etc. But don't pass pointers to
dynamic anythings. Certainly don't try and execute methods of objects.
Cheers,
Geoff
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in
message news:01c21e7b$8cbcf680$0d320a0a@User...
Looking through my source, I still think (maybe except for the call to
sysobject to retrieve the registered message-number) that I programmed
conform your sayings. If I understood well, every local created and so
locals in funtions called within a thread, are thread safe. When I pass a
static structure with static var's on creation of the thread, this must be
thread safe. When I reply to the main thread I do so with
PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg,DWORD(_CAST,lpVoid),MemF
ree_FileThread)
sThreadInfo.hWnd is the Mainwindow:Handle() so this must be thread safe.
lpVoid is the static structure that needs to be examined and free'ed
I DON'T call any methods (that belong to the main thread) from within the
other threads (except sysobject in postmessage).
So please, take a closer look at the little part of my program I sended in
the previous post, and just tell me wich part/line is buggy or at least not
thread safe. I believe that we're both talking about the chicken, but I'm
still getting the egg description instead.<g>
Rens.
"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message
news:_abT8.371954$o66.9...@news-server.bigpond.net.au...
To repeat earlier post ( of me on this subject ) you should be using
'RegisterWindowMessage' for creating your own messages and not
'WM_USER+<SomeOffset>'. ( Just a friendly hint ;-) )
Frans
"Ginny Caughey" <ginny....@wasteworks.com> wrote in message
news:afi4po$emus8$1...@ID-144704.news.dfncis.de...
To do anything with shared memory ( between threads ) you should at least
use 'EnterCriticalSection()' and 'LeaveCriticalSection()' calls, and maybe
you even need to have a look at 'Mutex's and other 'Waitable'-objects and
functions ( in the windows API ) that make use of this kind of processing
( like semaphores etc ). The best way to cross the process border is using
windows messages and sending then with 'PostMessage()' and not using
'SendMessage()', using 'PostMessage()' makes for easier serialization.
Before tackling things like this you should also have a look at 'Programming
Windows' by 'Charles Petzold'. Or maybe consult your local specialist <g>.
Best Regards
Frans de Wit
( Your local specialist )
"Rens" <ren...@RemoveThis.wish.net> wrote in message
news:afk635$jie$1...@news1.xs4all.nl...
Also, have a look at the 'Black Voodoo Server' example. It makes extensive
use of multi threading.
Frans
"FDW" <fdewit_...@planet.nl> wrote in message
news:afkhri$7ba$1...@reader09.wxs.nl...
Ok, but I don't think that's the source of his problem. Also note that
RegisterWindowMessage is only required when you are using messages across
multiple applications, and using it on Win95/98/Me requires the Microsoft Layer
for Unicode Support.
Ginny
"FDW" <fdewit_...@planet.nl> wrote in message
news:afkhe3$761$1...@reader09.wxs.nl...
> So please, take a closer look at the little part of my program I sended in
> the previous post, and just tell me wich part/line is buggy or at least
not
> thread safe. I believe that we're both talking about the chicken, but I'm
> still getting the egg description instead.<g>
There is not enough of your code here to do that - we've done enough
identifying a number of unsafe practices but you seem to resist our
assessment. In fact, it would be better if you were to provide a cut down
app that we could run. I don't agree with your further assessments below but
I'd want to see the code in its native form. Perhaps you should also
consider Frans' recent advice re Critical Sections and please, do read the
Black Voodoo paper.
Geoff
"Rens" <ren...@RemoveThis.wish.net> wrote in message
news:afk635$jie$1...@news1.xs4all.nl...
> Hi Ginny and Geoff,
>
> Looking through my source, I still think (maybe except for the call to
> sysobject to retrieve the registered message-number) that I programmed
> conform your sayings. If I understood well, every local created and so
> locals in funtions called within a thread, are thread safe. When I pass a
> static structure with static var's on creation of the thread, this must be
> thread safe. When I reply to the main thread I do so with
>
PostMessage(sThreadInfo.hWnd,SysObject():RegWinMsg,DWORD(_CAST,lpVoid),MemF
> ree_FileThread)
> sThreadInfo.hWnd is the Mainwindow:Handle() so this must be thread safe.
> lpVoid is the static structure that needs to be examined and free'ed
> I DON'T call any methods (that belong to the main thread) from within the
> other threads (except sysobject in postmessage).
>
>
> Rens.
> Ok, but I don't think that's the source of his problem.
I'm sure it's not, but using 'RegisterWindowMessage' avoids all posible
message collisions. And some other benefits.
> and using it on Win95/98/Me requires the Microsoft Layer
> for Unicode Support
I did no know that one.
Frans
"Ginny Caughey" <ginny....@wasteworks.com> wrote in message
news:aflj3q$figsu$1...@ID-144704.news.dfncis.de...
I'll go back to my drawingboard. The sysobject() will be removed or placed
within a critical section. If I find any other dynamic variables between
threads, I'll take action.
BTW I did read the Black Voodoo paper, this is where I first found the
dynlock() solution.
Just one question stays open for me:
Is a local dynamic created object in a function safe WITHIN that function if
the function is called from a worker thread? Or can the reference to this
object get obsolete because the GC (Re)moved the object while busy in
another thread not seeing this reference?
Rens
"FDW" <fdewit_...@planet.nl> wrote in message
news:afkhri$7ba$1...@reader09.wxs.nl...
The 'LOCAL' dyn-var will only be un-allocated by the GC if it looses scope,
meaning it will only be collectable after the function/method is terminated.
Frans
"Rens" <ren...@RemoveThis.wish.net> wrote in message
news:afmrrh$rre$1...@news1.xs4all.nl...
What Frans said.
Ginny
"Rens" <ren...@RemoveThis.wish.net> wrote in message
news:afmrrh$rre$1...@news1.xs4all.nl...
It's getting clearer now. (at least I think) {;-))
Thanks,
Rens
Stay of the booze, and keep on reading that MSDN doc <g> ;-)
Frans
"Rens Renooij" <R.Renooij@-RemoveThis-thegardenspecialist.com> wrote in
message news:01c220cc$c96d5cc0$0d320a0a@User...