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 Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Suggestions For Tablet Locking UP

Status
Not open for further replies.

AlastairP

Technical User
Feb 8, 2011
286
AU
I have an application that I have written for our technicians to use on tablets while conducting asset maintenance.
For the most part the application is running OK.

However, periodically the technicians are reporting that after 30-45 minutes of continuous use, the application will freeze up for a few minutes. The screen with go grey\dim and sometimes get the "not responding" message "Would you like to wait or exit" etc
I have not been able to reproduce this issue.
The one thing though, the problem does seem to be reported by a specific person, so initially I tried swapping tablets.

Now these tablets are low power/long battery life Windows 8 tablets.
I am beginning to think that the technicians are forgetting that these are a little on the slow side.
Some operations cause a little lag, which would not be noticable if the application was run on a desktop.

So perhaps they are clicking the buttons twice because they did not get instant reaction to the first click. Or being a touch screen, specific techs are clicking the button twice accidently.

I could wrote some code in the class to prevent the command button from executing the click event twice.
The only way I think I could do it would be someting like:

Code:
this.enabled=.f.
this.refresh()
&& do click event
this.enabled=.t.
this.refresh()

But before I go down this road, is there a way to prevent windows from thinking the program is "Not Eesonding" ?
Or get the application to ignore any input while code is executing, thus preventing Windows from thinking the application is "not Responding"?
Any suggestions would be appreciated







 
If you do some longer query there is not much you can do.
DOEVENTS FORCE will make your app responsive, but it's a command, so you can only do it between other commands.

Index correctly and also win8 tablets should run faster. It's your test drive, actually, that queries also don't take more than 3 seconds even on slower clients, despite for longer queries on large tables, where it might be acceptable.

To prevent double clicking set the form.MousePointer = 11 temporary, that will prevent the mouse to click, unless you set it back to 0 (default).

Bye, Olaf.
 
Hi Alastair,

I have occasionally seen applications where every command buttons has code like the following in the Click event:

Code:
THIS.Enabled = .F.

* Code here to do whatever you want the button to do

THIS.Enabled = .T.

In other words, exactly the same as you have, but without the two Refesh calls, which serve no purpose at all.

But I've never seen the need to do this myself. In general, if you click on a command button while a process is running (that is, if you are anywhere other than at READ EVENTS), the click will be lost. For that reason, I don't think this approach will solve your problem.

That said, if you do decide to use the above approach, you should do so generically, at the class level. You would add a custom method to your base button class; call it, say, DoClick; you would call that method fromn the base class's Click, after disabling the button, but before re-enabling it; then, at the instance or sub-class level, you would write code in DoClick to do whatever you want the button to do.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I do exactly what you have suggested, and without refresh. You can try this.enabled = .t. in the valid(), when you have multiple returns.

If the cpu slower than the desktop. You may try creating a variable and set it to true in the click(). Then on top of the click(), issue a massage like 'Your request is in progress' and return, else continue the click() event. Set back to false once process completes.


nasib
 
You can use multithreading to send the current locking task to a parallel worker thread,
this way your app will be always responsive, and a callBack routine will get called when the
task is done.

Though I have only used Vfp2C32 createThreadObject function ( ) ,
ParallelFox ( ),
seems easy to implement at first time and it's very well documented even with videos online.

You can check another great library from Christof Wollenhaupt ( dmult.dll ) and a recent
presentation Kevin Ragsdale made on the OFUG ( Online Foxpro User Group ) about it - Todd Landrum
posted links on :


Marco
 
Problem with parallel processes (ParallelFox) is, that you won't have a query result in your own data session. So only a multithreading solution is usable in that case.
Another maybe simpler to implement idea is having a separate thread to only care about UI interaction and responsiveness. I haven't thought that through and tried, it may fail due to the fact you'd need to start/create forms in that responsiveness thread, which makes it the main thread anyway.

I know as Calvin Hsia came with his multithreading approach I tried populating a grid via a worker thread and failed quite miserable with that. Haven't looked back at that.

Before you try solving the responsiveness with threads, see if your queries are optimised. Do you work with tables with millions of records and more than 100MB size? Everything smaller is queried in the blink of an eye even in a single core atom CPU with appropriate indexing.

Bye, Olaf.
 


In that case you use xmltocursor and return that to your callback function.
In fact you would normally pack all the background process response in xml.

Marco

 
The connection to the server is only used when "Syncing" data off the tablet to the server.


Regards
Alastair

 
> I tried populating a grid via a worker thread and failed quite miserable with that

In detail: the new thread works in the same datasession, but writing to a workarea the main VFP thread reads (eg via the grid) seems to causes conflicts not foreseen, as VFP was not intended for multithreading.
Multiprocessing is cleaner. Doing any query in a seperate VFP session and transferring data via CURSORTOXML and XMLTOCURSOR causes more trouble than you solve, partly because each new VFP session causes a runtime initialisation, uses up more memory, partly because while CursorToXML is fast, XMLToCursor is not very well implemented.

Your main goal should still be optimising your query. There is nothing wrong with a weaker CPU, VFP) is from 2004, was developed for single thread/code usage and any CPU today offers enough processing speed.

Do you have an example of a slow running query and about stats on the involved table? We might simply make this a rushmore optimizaion lesson.

Bye, Olaf.
 

Hi Olaf, you'll never have problems using cursortoxml/xmltocursor while both functions feed each other, and the Vfp runtime only initializes the first time per dll ( each new thread shares the same runtime , vfp just instantiates a new object on a new apartment thread ) or once per worker thread on ParallelFox, so memory consumption is low ( about 25k for each new thread when using mtdlls ). In fact the apartment model threading, the session class, the fact you can create tables with sharing possibilities, makes vfp a great tool for multithreading.




 
A bit of further investigation is needed:

- How much memory on the device?
- 64 or 32 bit Windows?
- Atom processor?
- Are the local tables properly indexed?
- What else is running on the device at the same time?
- How big is the disk and how much free space?


Craig Berntson
MCSD, Visual C# MVP,
 
mplaza,

as far as I see, or the last time I looked, ParallelFox didn't start new threads, but new processes. There is no sharing of the runtime DLLs for that reason. XMLTOCURSOR has no problems turning XML back to a cursor, which was generated by CURSORTOXML, correct. But it's slow with larger data sets. I once used that as a data access interface and stopped using it for that performance reason.

ParallelFox might have changed, since I last looked, but only the other solutions you proposed start new threads, AFAIK.

I downloaded the newest version and it still works as I remembered. For the reason of slow XML converision, the worker class has a ReturnCursor method, saving a cursor to a DBC table on disc and reading back from that. It is faster in my experience, too. OS caching helps this to remain in cached memory anyway, but there is no XML parsing and validating done, as with XMLToCursor. There is a turn around point somewhere, you don't have to have huge datasets to be faster by saving to DBF in a worker process and reading back in the main process.

Bye, Olaf.
 

You're right ParallelFox creates a pool of worker exes like foxisapi ( did'nt meant to write thread but "process" ups! ). If you work vfp2vfp on the same machine no need to convert to xml and back, you can use shared tables ( the callback says simply your result its named vv982.tmp go read it ). But I like more using xml.. In this case we could simply do a filetostr to a dbf and create a xml node, then send it back like xml response to your calling function, even compress it before etc. Another approach for large datasets you could tell the long process to end its job ( say it generates a 200mb file ) and delegate the response retrieve to another component, like chunking does in http to "download" the result or odbc does on the background to fetch records from server backend on async mode-having a "response reader" with progress bar indicating records downloaded/speed/etc.. it depends which scenarios we manage...
 
Hi Craig

A bit of further investigation is needed:

- How much memory on the device? = 2gb
- 64 or 32 bit Windows? = 32bit
- Atom processor? = Atom Z2760 Dual-core CPU @ 1.8Ghz
- Are the local tables properly indexed? = I think so, will double check and confirm this later
- What else is running on the device at the same time? = no other applications, some background services for sure
- How big is the disk and how much free space? = 64 gb total, free space 32 gb


 
The specs are quite fine.

Do you have an SSD drive or HDD? 64GB sounds like an SSD. In many cases SSDs are not optimised for database access, but for continuous reading, eg loading large documents or a video, but not random access of records. An SSD then can be much slower than a normal HDD.

Bye, Olaf.
 
After MUCH testing and observing the technicians operating the tablet, I have come to the conclusion that the issue is in part related to the way the people are using the tablets.
When they are using the application, they tend to go into "Auto Pilot" mode and sometimes their clicks are a few ahead of the actual process. Then occassionally the tablet will freeze up for a few moments, and they make it worse by continuing to click on the application in some vain hope it will recover quicker.
All they are doing is adding more load to the tablet.
At that point sometimes the screen will go dim and the windows message will appear asking if you want to wait or close the app.
If you choose to wait, it can take some minutes to right itself.

Also I have noted, that even though the tablet specs seem reasonable, in reality, the tablet is optimised for long battery life, so it does not take much to slow it down.

I have provided more training to the techs, and so far they have not reported any more occurances.
I will start working on revamping the click events to help with the situation

Thank you all for your help

Alastair
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top