|
-
Jul 13th, 2019, 05:01 AM
#34
Re: VB6 Threading-Examples using the vbRichClient5 ThreadHandler
 Originally Posted by ColinE66
...it turns out, as I've since observed that any thread that is exited whilst inside a loop is susceptible to this crashing.
Was not able to reproduce that on either Win8.1 nor Win10 - but got "successful" on WinXP...
Studying the code in your ThreadDll (JobRunner.dll) - I was able to prevent the crashes, by adding
an additional CancelCheck-line into your Main-Loop:
Code:
Public Sub Test(pCommand As String)
Dim i As Long
mCancelled = False
For i = 1 To 20
If Cancelled Then Exit Sub
RaiseEvent Iteration(i)
ExecCmd pCommand
Next i
RaiseEvent JobComplete
End Sub
The idea behind it being simply, to *prevent* the ThreadHandler-mechanism, to send "any more events after an external cancelling"
(via the Named-Pipe I use underneath for communication)...
Since a clientside CancelExecution will (in addition to setting a "Cancel-Flag" in shared memory) also close the "communication-channel" (the "old pipehandle") -
followed by re-opening a new pipe-handle immediately after that (for the next call of a "Public Main-Routine" in your Server-Dll).
I assume, that an attempt to use the (already closed, or "marked for close") "old pipe-handle" (by trying to send Event-Data over it from the server-side),
is causing the crashes (at least on XP - probably also on Vista and Win7).
Will try to look into it, when I find time (to make it more bullet-proof, ignoring Event-Send-Requests when the Thread-Handler-Classes are in "CancelExecution-state") -
though the best way to prevent these crashes seems to me, to really make sure to leave the "Main-Public-Function" as early as possible, when an outside Cancelling was detected
(no matter how deep you were in some private Sub-Routines - the Cancel-Exits should be honored "further up the stack" as early as possible as well...).
Addition:
Looking further at the code in your threaded JobRunner.dll, I've seen that you're waiting for
5000msec (5seconds) for the shelled process in question to be finished (via WaitForSingleObject).
During that time, the thread will not be able to detect outside cancelling -
and that "clashes" with: TH.TimeoutSecondsToHardTerminate (which is by default at 3seconds).
Hard thread-termination (via TerminateThread-API, which is called under the covers when TH goes out of scope) needs to be avoided -
better would be, to allow the thread to close "gracefully" - by ensuring a TH.TimeoutSecondsToHardTerminate
which is greater than the "maximum-time the thread-dll-class cannot react to outside cancel-signalling".
And another idea would be (since you already use other processes to do the actual work, which are by definition "asynchronous"),
to not use any threading-helpers at all - instead a simple "Process-Pool-Class" could be enough, which checks via an internal timer,
whether the "shelled processes" are finished with their Job(s) - or not).
Here a simple "wireframe-class" you could expand on, making some experiments:
(the workhorse here is the Helper-Object, which is returned by Wsh.Exec(CmdLine)...
Code:
Option Explicit
Private Wsh As Object, Processes As New Collection
Private WithEvents tmrCheckProcesses As cTimer
Private Sub Class_Initialize()
Set Wsh = CreateObject("WScript.Shell")
Set tmrCheckProcesses = New_c.Timer(100, True)
End Sub
Public Sub AddAndExec(ByVal CmdLine As String)
Processes.Add Wsh.Exec(CmdLine)
End Sub
Private Sub tmrCheckProcesses_Timer()
Const WshRunning = 0, WshFinished = 1, WshFailed = 2
Dim i As Long, P As Object
On Error Resume Next
For i = Processes.Count To 1 Step -1 'loop backwards, to be able to delete from the Collection
Set P = Processes(i)
Select Case P.Status
Case WshRunning
'set a flag to the outside, or something, signalling this state
Case WshFinished 'successful finishing
Processes.Remove i 'a normal remove from the collection should be enough
Case WshFailed
Processes.Remove i 'remove this from the Col as well,
P.Terminate 'but just in case the process is still linering, try to terminate it as well
'If P.ExitCode = SomeValue Then
'just to hint at another property, the Wsh-Process-Object offers
'End If
End Select
Next
If Err Then Err.Clear
End Function
HTH
Olaf
Last edited by Schmidt; Jul 13th, 2019 at 05:41 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|