1. Jason Lipman
  2. PowerBuilder
  3. Monday, 8 January 2024 18:50 PM UTC

PB 2017 R3

Hey everyone! I've never tried this before... Is there a way to trap a keypress while in a loop?

We are processing over 4 million rows in a loop. To handle memory, I am resetting and retrieving appropriate untouched rows after every ### rows. I can cancel the process with DBCancel and the RetrieveRow event during the retrieve. But I would like to allow the user to cancel while looping the ### number of rows if possible as well.

Any ideas?

Thanks!

Jason Lipman

Roland Smith Accepted Answer Pending Moderation
  1. Tuesday, 9 January 2024 17:49 PM UTC
  2. PowerBuilder
  3. # 1

How many rows are processed between commits? Doing a commit after every row will slow it down. I would try every 100 rows to start. If too many updates are pending, the commit will take a long time and there might be blocking on the updated tables.

Comment
  1. Jason Lipman
  2. Tuesday, 9 January 2024 19:41 PM UTC
Roland, I am actually looping a 4.6 million row table only extracting the Blob and saving it out to a directory for use by a different tool. To prevent any memory issues, I was thinking of re-retrieving the untouched data every 200 rows or so. I am not yet sure how many rows I can handle before there are memory concerns. I was also considering using GarbageCollect after every ??? rows to help prevent issues.

  1. Helpful
  1. Roland Smith
  2. Wednesday, 10 January 2024 16:04 PM UTC
I hope this is a onetime thing!

Can you do a retrieve with only the minimum columns needed to feed into a SELECTBLOB statement? The SELECTBLOB and code to write it to disk could go into the RetrieveRow event. A Yield function could be used to allow for updating progress on the window.
  1. Helpful
There are no comments made yet.
Jason Lipman Accepted Answer Pending Moderation
  1. Tuesday, 9 January 2024 15:19 PM UTC
  2. PowerBuilder
  3. # 2

Thank you for the responses! Yield worked beautifully. In my case, there was no need for multi-threading. I think I did use Yield() many years ago, and did not recall this very simple solution. 

Jason

Comment
  1. John Fauss
  2. Tuesday, 9 January 2024 16:04 PM UTC
That's great news, Jason! Thanks for letting us know what worked for you.
  1. Helpful
There are no comments made yet.
John Raghanti Accepted Answer Pending Moderation
  1. Tuesday, 9 January 2024 13:10 PM UTC
  2. PowerBuilder
  3. # 3

We have done something similar. We had to put a Yield() into the loop. We added a boolean instance variable

 

ib_cancel = False

 

Then trapped the keypress and set the boolean to True. Inside the loop after the Yield(), check the value of ib_cancel and stop the processing if needed.

 

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Monday, 8 January 2024 19:17 PM UTC
  2. PowerBuilder
  3. # 4

Hi, Jason - 

Some ideas to consider:

1. Async=1 DBParm option (not supported with the SQL Server SNC or MSO database client interface). More info here:
    https://docs.appeon.com/pb2022/connection_reference/Async.html

2. If the app is in a wait state while the database request is being executed and Async=1 is not an option, then using the Yield() PowerScript function won't help. You would need to execute the database operation in a separate thread in order to keep the main/GUI thread available and responsive.

Here are a couple of tech articles that may help:

    https://community.appeon.com/index.php/articles-blogs/tutorials-articles/2-powerbuilder/325-why-unresponsive-application-windows-are-ghosted-by-the-windows-o-s

    https://community.appeon.com/index.php/articles-blogs/tutorials-articles/2-powerbuilder/339-free-my-gui-multi-threading-in-powerbuilder

Best regards, John

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.