Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multi-tasking / grid refresh 2

Status
Not open for further replies.

vinemicros

Programmer
Apr 4, 2001
12
GB
I had a very odd problem the other day, that I solved, but it's raised some rather nasty questions.

The problem was that I had a nice grid, with some fields in the grid calling a text decryption function ('decrypt') in my main procedure file (utility.prg). Users could then double click on a record in this grid, and view and edit the record. This form that allows the viewing/editing also calls the decrypt function.

The problem was that now and then the two would clash - ie. the user double-clicks the grid record, and whilst the form displaying this data is calling the decrypt function in order to display decrypted data, the grid in the background refreshes itself and also calls the decrypt function - *whilst* the first decrypt function is performing the form's decryption!

This would have been okay, but my decryption function uses the random number generator with a seed value. With the second call of the decrpytion routine, the seed is reset. When this second call ends, the first resumes, with of course completely the wrong random number sequence - leading to unintelligible data.

I sorted this out by adding a flag to tell the grid that the decrypt function was busy.

HOWEVER, what else is going on in Visual Foxpro (SP5) that could cause such multi-tasking?

I have lots of forms and grids with their own datasessions and file locks. I also have a list of very strange problems like 'Record not locked' even when I *know* the record *is* locked. These errors can't be reproduced, and I can only presume it's because some other multi-tasking 'feature' is getting datasessions and databases all confused.

Is there a way to turn off such multi-tasking in FoxPro?

Am I going to have to write all my code knowing that at *any* point in the code another piece of code could be run (eg. to refresh something)?
 
Interesting, since VFP is a single-threaded, non-multitasking app. I think what you described can only happen if you are using an ActiveX control or calling an external .EXE. somewhere in the fine manual is a discussion of how to wait for an executable to finish before going on. Try the help for the RUN command. Good luck.
 
Hi!

Check out _VFP.AutoYield value. Probably in your application it allows events processing between code lines causing some rare, weird and strange behavior. Disabling this speeds up programs, but will have to do some tricks to refresh controls between code lines, for example, to refresh progress bars.

Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Dear friend,
Yes you can turn off such multi-tasking in FoxPro simply by using the right technique to implement you function.

Probably by now you already heard about In-Process and Out-Of-Process COM servers.
The scenrio you described definitely points to Out-Of-Process COM server.
All you need to do to solve your problem is to take your code (the code of this function) and make a Out-Of-Process COM and compile it as DLL (Out-Of-Process) server.
If you already know how to do that, life is good.
Otherwise, Check the help for developing ActiveX COM servers, or feel free to ask how to do it, I will be more than happy to walk with you through the procedure step by step.
Hope this will help you.
Thanks Walid Magd
Engwam@Hotmail.com
 
Ok, thanks for all your help.

The _VFP.AutoYield=.F. answer seems to have done the trick.

With _VFP.AutoYield=.T. I think what was happening was this:
1. The user double-clicked on the grid record. This, of course, makes the nearest word get highlighted.
2. The code starts-up the editting form.
3. The form's Init code calls the decrypt function...
4. The grid, of course, loses focus.
5. *Whilst* the editting form is still running it's Init code, the grid is refreshed, since it's no longer got the focus.
6. The grid finishes its Refresh.
7. The form finishes its Init code.

With _VFP.AutoYield=.F., the grid (seems to) correctly wait for the Form's Init code to finish before refreshing itself.

I would guess that the grid refresh is more under the control of Windows than of FoxPro, and hence that's why it's losing the normal single-threaded code execution. It could also be down to the double-click highlighting the nearest word in the grid record. I didn't have the patience to try anything else out, but would be interested in what other people think.

Any further thoughts?
 
Hi!

No, its not a normal losing of single-threading.
Remember that you call the decrypt function as a function in the control sources (or Dynamic* properties). These expressions are required to be evaluated to paint grid correctly. When WM_PAINT windows event fired for form with grid, grid repainting requires evaluating of all these expressions, thus it requires to call these UDF functions.
Anyway, this is not a multi-threading in the full sense, because the Init method of the form called by double click waits just after the code line when grid repainting occurred (you can see this in the call stack). Ususal multi-threading is when commands run simultaneously, that could be done for VFP only with huge effort related to API and threading/processes. So, from the VFP point of view we can suggest that this is multi-threading, when from the OS point of view it is the same process and thread.
BTW, the same happens when you have ON KEY LABEL or ON ESCAPE defined and user presses that key during program execution. The same is related to ON SHUTDOWN. All of these things do not happen when _VFP.AutoYield disables events processing between code lines.


Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Thanks Vlad, that's explained things nicely.

By the way, with _VFP.AutoYield=.F., another form I have with a Treeview ActiveX control gets screwed up - an OLE error saying something like 'Element not found' when trying to add a new child node after about 100 nodes are added.

With _VFP.AutoYield=.T., this doesn't happen.

I presume that maybe the Treeview control is relying on being able to handle old events before newer ones are added - ie. the new event of adding the node relies on the previously added nodes' events!
 
Help file recommends to set AutoYield to .T. for forms with ActiveX controls, or at least wrap the code for ActiveX that causes such crashes as you described. _VFP.AutoYield property could be changed any time you want without any bad effects.


Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Thanks Vlad. What do you mean by 'wrap the code'? Put it in a container?
 
No. Something like I do usually with thisform.LockScreen

local llEventsEnabledHere
llEventsEnabledHere = !VFP.AutoYield
VFP.AutoYield = .T.

.... && your wrapped code here

VFP.AutoYield = !llEventsEnabledHere






Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top