|
|
|||||
|
|
|
Random errors: what can cause them
|
|
||
|
First, let's see what's happening when you use a multitask
-1 to interrupt a process, which is a legitimate way to code, as long
as you are careful: In your main process loop, you are going to write
something like: When you are doing that, your main process loop is interrupted each time you reach the multitask(-1), and if the user has previously clicked on the interrupt button, the click event will fire and your interrupt button code will be executed. At the end of this code, your main process code will continue at the line just after the multitask (i.e. the test on the flag)... Problems are starting as soon as you deviate from that very simple schema... First, if you put mode code in your button than just setting a flag.... And the problem is to define precisely what MORE code means... At some point, when the number of line executed (and therefore when the execution time) exceed some limit, the main process will NOT restart at the line following the multitask... It looks like the return address was lost somewhere... You have therefore a code that was interrupted and never finished, and if you were allocating dynamic objects in that code, you didn't have the chance to delete them... Here is your memory leak... That case is quite simple and easy to find, just remember not to have any lengthy code in that button (or in a procedure called fro that button). But thinks are getting more complicated when you are not doing more complex process... Let's say that you are have multiple windows open at any given time (like any modern UI does), and that you are using events in some of them (by example to process the resizing on the fly, detect the click on a table column, etc...)... And now you have this lengthy process in one window and you want to display the content of the record currently processed... The normal way to achieve that is to do a multitask() (no minus sign this time) in your process, just after you set the value you want to display in a window field... The one thing that is NOT written in any help file I'm aware of is that when the code encounter a multitask, events are firing... Which means that if during your process, the user TRIED to resize a window, or clicked on a table column, these events that were quietly waiting to be processed are going to be processed now, in the middle of your normally not interruptible code... At least some of them will... And depending of the length of the event management code, the program will continue or NOT at the line following the multitask... And that's not the end of it... Till now, we just had one process interrupted, and possibly some objects not cleaned in memory, so nothing TOO bad (except that your process never finished of course :-) But what happen when all that is part of the same
class? More precisely, what happen when one dynamic object was running
the main process in one of its methods, and when the event management
is executed in another of its methods... Of course, I'm not aware of any
inside information on the WinDev compiler (or should I say interpreter),
but I have done enough work both on compilers in general and with WinDev
to have a good idea on how things are organized... Each instantiated object
clearly has internal pointers, stack of calls, and so on... It can be
organized in one general stack or with one stack per object, but still,
any compiler/interpreter needs to keep track of the returning address
for each call of a method.... Let's have a look at what this kind of stack
looks like when the main process has been called, and when it has called
a secondary process:
|
|||||
| Links: |
|
||||