Open DBF’s not visible in BackgroundWorker second thread.

This forum is meant for questions and discussions about the X# language and tools
Post Reply
RolWil
Posts: 68
Joined: Mon Jul 18, 2022 3:16 am

Open DBF’s not visible in BackgroundWorker second thread.

Post by RolWil »

Hello XSharpers;

Problem: open DBF’s not visible in BackgroundWorker second thread.

In my application, there is a utility that performs calculations on individual’s health benefit costs.

This calculation can take some time depending on how many individuals are being calculated, so In order to show some activity, in the Harbour-Clipper version, I would simply put the current individual’s Id up on the screen which took all of one line of code.

In Windows this is a much complicated affair (perhaps someone can direct me to a simpler approach than the one I've taken):

In my X# conversion, there is a ‘start’ button on the utilities’ form; at the time the calculation form is opened, I have about a dozen open DBF’s. My understanding is that, being Windows, once the calculation is started, the form never gets control again until the calculation has completed, so there is no simple way to update a label on the form.

So, I’ve been trying to use the BackgroundWorker widget (which I named "bgwUserID" to have the calculation run as a second thread. I set the BackgroundWorker’s DoWork() method to my main processing function named “DoCalculation()”; the ‘Start’ button initiates the BackgroundWorker's “RunWorkerAsync()” function. TheBackgroundWorker’s "ProgressChanged" method updates a label with the current individual's ID.

The open DBF's no longer appear inside the second thread. I assume I’m doing something wrong, but haven’t a clue, perhaps you can help.

PS: I can’t use a “Progressbar” because I don’t know ahead of time how many individuals will be in the calculation since it depends on the user’s selections.
PRIVATE METHOD btnCalc_Click(sender AS System.Object, e AS System.EventArgs) AS VOID STRICT

// DBFs are open
SELF:bgwUserID:RunWorkerAsync()

RETURN
END METHOD

PRIVATE METHOD bgwUserId_DoWork(sender AS System.Object, e AS System.ComponentModel.DoWorkEventArgs) AS VOID STRICT

// no DBF files apear as "open" at this spot
DoCalculation()

RETURN
END METHOD
Thanks for your help!

My “Stack”:

Windows 11

VS 2022, Project template: “Harbour Console Application”;
Project references:
-Mscorelib
-System
-System.Core
-System.Data
-System.Data.DataSetExtensions
-Syste.Xml
-System.Xml.Linq
-XSharp.Core
-XSharp.Data
-XSharp.RDD
-XSharp.RT
-XSharp.RT.Debugger
-XSharp.SQLRdd

X# Ver 2.18.04

SQLExpress V 16.0.1000.6
User avatar
wriedmann
Posts: 3748
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by wriedmann »

Hi Roland,
in X# the workareas are separated per thread. Therefore in one thread you cannot see the workareas of the other threads.
I don't know if there is a possibility to access all workareas of all threads - that is a question for Robert.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
RolWil
Posts: 68
Joined: Mon Jul 18, 2022 3:16 am

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by RolWil »

Thanks Wolfgang,

I thought that might be it; I had tested public global variables and they ARE visible in the second thread. Is there anything else that is not 'visible' or accessible in a second (or more) thread that you might know of?

Cheers
Roland
User avatar
Chris
Posts: 4844
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by Chris »

Hi Roland,

It's very easy to allow the form to repaint itself while inside a loop, just issue a Application.DoEvents() every once in a while (not in every single iteration, this is overkill and might slow down execution).

Just be aware that this will enable the user to do other actions like open other windows or close the active one with the X button, so you may want to make sure you avoid this from happening.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
RolWil
Posts: 68
Joined: Mon Jul 18, 2022 3:16 am

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by RolWil »

Thanks Wolfgang, I had read somewhere that this is quite time-consuming. I'll give it a try. I already disable all but the 'Stop' button ... which I intended to use for just that.

Cheers.
User avatar
robert
Posts: 4473
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by robert »

Guys,
You can indeed (with some programming) access the open DBFs in other threads.
But I would not recommend it, especially when indexes or filters are involved: the macro compiler is used to evaluate expressions and these expressions are evaluated in the context of the "current" area.
If you really want to do this:

The DataSession class contains a static property Sessions.
DataSession inherits from Workareas.

Each session in this property contains the list of open DBFs in a thread. The session has a property Thread that contains the thread for which a session was created.
The WorkAreas class has a method GetRDD() that gets an RDD object for a workarea number

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
leon-ts
Posts: 431
Joined: Fri Feb 03, 2017 1:43 pm

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by leon-ts »

Hi Roland,
I would suggest that you move your calculation function to a second thread without being tied to the currently open workareas of the main thread. That is, in the second thread you will re-open all the files you need for the calculation in shared mode + read-only (just for productivity), perform the calculations and close the files. In this case, in the second thread you can use the same workarea aliases that are already defined in your algorithm. These aliases will not conflict with the same aliases on the main thread.
Best regards,
Leonid
User avatar
Chris
Posts: 4844
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by Chris »

Roland,

In addition to what the guys said, did you also see this reply https://www.xsharp.eu/forum/topic?p=29495#p29495
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
RolWil
Posts: 68
Joined: Mon Jul 18, 2022 3:16 am

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by RolWil »

robert wrote: Tue Apr 23, 2024 6:15 am Guys,
You can indeed (with some programming) access the open DBFs in other threads.
But I would not recommend it, especially when indexes or filters are involved: the macro compiler is used to evaluate expressions and these expressions are evaluated in the context of the "current" area.
If you really want to do this:

The DataSession class contains a static property Sessions.
DataSession inherits from Workareas.

Each session in this property contains the list of open DBFs in a thread. The session has a property Thread that contains the thread for which a session was created.
The WorkAreas class has a method GetRDD() that gets an RDD object for a workarea number

Robert
Interesting and good to know for debugging, thanks Robert. For now, I'm going to try and achieve what I need to with a more "traditional" (safe?) approach.

Roland
RolWil
Posts: 68
Joined: Mon Jul 18, 2022 3:16 am

Re: Open DBF’s not visible in BackgroundWorker second thread.

Post by RolWil »

leon-ts wrote: Tue Apr 23, 2024 9:32 am Hi Roland,
I would suggest that you move your calculation function to a second thread without being tied to the currently open workareas of the main thread. That is, in the second thread you will re-open all the files you need for the calculation in shared mode + read-only (just for productivity), perform the calculations and close the files. In this case, in the second thread you can use the same workarea aliases that are already defined in your algorithm. These aliases will not conflict with the same aliases on the main thread.
Thanks Leon, I had done exactly this last night and it worked. I already had the calculation ''function' in a separate thread in order to use the backgroundworker widget, it's the open files that caused me the problem. I have a library function to open necessary files, so it was fairly easy to add this to the calc routine.

I did notice something odd though: if using alias->(dbclosearea()) and the alias is not open, it results in an error, so have to check first then close.

Cheers,
Roland
Post Reply