On AsyncDo and ThreadSafeCall  SOLVED

PDF-XChange Editor SDK for Developers

Moderators: TrackerSupp-Daniel, Tracker Support, Vasyl-Tracker Dev Team, Sean - Tracker, Paul - Tracker Supp, Chris - Tracker Supp, Tracker Supp-Stefan, Ivan - Tracker Software

Forum rules
DO NOT post your license/serial key, or your activation code - these forums, and all posts within, are public and we will be forced to immediately deactivate your license.

When experiencing some errors, use the IAUX_Inst::FormatHRESULT method to see their description and include it in your post along with the error code.
Post Reply
zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

On AsyncDo and ThreadSafeCall

Post by zarkogajic » Sat Nov 30, 2019 2:52 pm

Hi support,

I'm looking for a way to do something with a bunch of pdf documents in separate thread(s) ... browsing the sdk help, and I think I've found what seems to be the way to go - and would need some guidance / confirmation / explanations before I start heavy coding...

I have an array of PDFs and for each I'd need my custom IOperation to be executed *not* in the main app thread. I also need to be able to cancel the process at any point - something similar to how the op.search (inside a folder) works - the search results are populated in a different thread and the Stop button can be used to stop the search.

Here's how I think this should work and would like your comments :

Code: Select all

//pseudo

for each pdf do
{
1. IPXV_Inst::AsyncDo to run an IOperation (with pdf as input parameter) in background thread
2. During the execution of IOperation.Do periodically call IPXV_Inst::ThreadSafeCall 
3. In OnThreadSafeCall check main thread for "my stop flag" - if set exit the Do method (this will fire IPXV_AsyncDoCallback.OnFinishOp)
4. Check for stop flag in IPXV_AsyncDoCallback.OnStartOp to check if "this" operation in thread pool should even start executing.
}
Since there will be lots of pdfs the for lop will finish and the operations to be executed will be in some thread pool?

What will happen if the are operations still to be executed and I try to close the app (Inst.Shutdown)?

How may threads are used by sdk? Is this specified in Preferences - Performance - Threads / working threads ? If so, how do you determine the number of threads for "automatic" value?




-žarko

User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Fri Dec 06, 2019 4:05 pm

Hello zarkogajic,

Forwarded this one for Vasyl for further investigation.

Cheers,
Alex
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 1983
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: On AsyncDo and ThreadSafeCall

Post by Vasyl-Tracker Dev Team » Wed Dec 18, 2019 11:35 pm

Hi -žarko.

Sorry for delay with answer.
for each pdf do
{
1. IPXV_Inst::AsyncDo to run an IOperation (with pdf as input parameter) in background thread
2. During the execution of IOperation.Do periodically call IPXV_Inst::ThreadSafeCall
3. In OnThreadSafeCall check main thread for "my stop flag" - if set exit the Do method (this will fire IPXV_AsyncDoCallback.OnFinishOp)
4. Check for stop flag in IPXV_AsyncDoCallback.OnStartOp to check if "this" operation in thread pool should even start executing.
}
That looks good, excepting the switching from the working thread to the main thread just for check cancel of work. There exists other simple and safe way to cancel all tasks. You may use our IFlag-object:

Code: Select all

// create one 'global' IFlag-object:
auxInst.CreateFlag(&myCancelFlag);

// create and start all tasks and share with them this one myCancelFlag
for (pdf : listOfPdfs)
{
       MyOperation op = new MyOperation(pdf, myCancelFlag);
       pdfInst.AsyncDo(op, ..);
}

// inside the operation
MyOperation::Do()
{
       // do some work with m_Pdf
       if (m_CancelFlag.Value)
       {
              return; // cancel the task
       }
       // do some work with m_Pdf
}

// then in the main thread, in UI, to stop all work

OnBtnCancel()
{
     myCancelFlag.Value = true;
     //
     // here, if you need, you may wait for all corresponding IPXV_AsyncDoCallback.OnFinishOp calls. 
     // Of course, while you wait, to keep the UI alive - you need also 'pump' all window's events..
}
- this method works without interlocking threads at all.
Since there will be lots of pdfs the for lop will finish and the operations to be executed will be in some thread pool?
Yes, the AsyncDo uses special internal thread pool.
What will happen if the are operations still to be executed and I try to close the app (Inst.Shutdown)?
For sure that is abnormal scenario. So before calling of Inst.Shutdown() I recommend you to wait for finish of each task, as I mentioned above. Especially when you working with documents in that tasks..
How may threads are used by sdk? Is this specified in Preferences - Performance - Threads / working threads ? If so, how do you determine the number of threads for "automatic" value?
Currently the thread-pool used by AsyncDo has a limits: you can run no more than 3 tasks at the time. So any other tasks will just wait for 'gap'.
Also the changing of the MaxNumOfWorkingThreads parameter in the Prefs/Performance - it may take effect on this. For example if you set 1 to it then the max-limit for the mentioned thread pool will be reduced to the 2 (because the minimum number of threads for that thread-pool is 2). To summarize all of it, the max-limit for that thread-pool calculates as:

Code: Select all

maxThreadsNum = Prefs.MaxNumOfWorkingThreads;
if (maxThreadsNum <= 0) // automatic
    maxThreadsNum = CpuCoresNum;
else
    maxThreadsNum = min(maxThreadsNum, CpuCoresNum);
maxThreadsForAsyncDo = min(maxThreadsNum, 3); // 3 - it can be increased in the future
maxThreadsForAsyncDo = max(maxThreadsForAsyncDo, 2);
Cheers.
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Thu Dec 19, 2019 9:45 am

Hi Vasly,

This is great, thanks! The IFlag is super handy.

Please do reconsider, in SDK, to allow increasing the max threads from 3 to whatever a developer specifies :)



User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Thu Dec 19, 2019 10:16 am

Hello žarko,

Note, that using the operations in many threads can only be done on the IPXC level, meaning using the IPXV_Inst and IPXC_Document. If the operations are used in the multiple threads on the living IPXV_Control then there can be many troubles - undo/redo data (history), modification of one document from several threads etc. Thus you should limit the usage to the Core level where no control, events and history are present if you want to do multi thread work.

Cheers,
Alex
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Thu Dec 19, 2019 10:54 am

Hi Alex,

Yes, was aware of that :) Thanks.


User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Thu Dec 19, 2019 12:11 pm

:)
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Mon Mar 30, 2020 9:51 am

Hi Support,

Just do double check: the methods of IPXV_AsyncDoCallback (OnStartOp / OnFinishOp) are *not* executed in the main thread, they are executed in the same thread where the Do() method of the IOperation takes place?


-žarko

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Mon Mar 30, 2020 3:35 pm

Hi support,

Did some tests: the answer is yes.


User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Mon Mar 30, 2020 4:51 pm

:)
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 1983
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: On AsyncDo and ThreadSafeCall

Post by Vasyl-Tracker Dev Team » Tue Mar 31, 2020 12:46 am

Hi žarko.

In the new upcoming build you will be able to change in runtime the limit for background threads (started by AsyncDo) via:

Code: Select all

pdfCtl.Inst.Settings["Performance.MaxThreads"].v = 16;
pdfCtl.Inst.Settings["Performance.MaxBackgroundThreads"].v = 8;
pdfCtl.Inst.FireAppPrefsChanged(PDFXEdit.PXV_AppPrefsChanges.PXV_AppPrefsChange_Performance);
Cheers.
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Tue Mar 31, 2020 5:43 am

Hi Vasyl,

Fantastic!


User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Tue Mar 31, 2020 8:05 am

:)
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Wed Apr 01, 2020 7:33 am

Hi support,

When adding IOperation "tasks" to the thread pool via Inst.AsyncDo - you are storing tasks in some queue like structure.

The order of task execution follows the order of adding to the queue.

So, if I do:

Inst.AsyncDo(IOp_1)
Inst.AsyncDo(IOp_2)
Inst.AsyncDo(IOp_3)
...
Inst.AsyncDo(IOp_N)

The execution will (kind of) be 1,2,3, .. N. We can say this is "normal" priority.

Is there a way for AsyncDo to specify the priority of the IOperation?

Say I'm adding the next task AsyncDo(IOp_M) - I'd like this one to be executed as soon as possible (when one of the threads used is finished executing "normal" priority tasks) - so like having "high" priority (kind of a new OpExecFlags value).

?

p.s.
I presume the answer is no, but experience tells me "you never know" :)

-žarko

User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Wed Apr 01, 2020 1:19 pm

Hello zarkogajic,

From what I know, the AsyncDo uses a highest priority thread pool in the thread manager that is being registered when the instance is created. Basically what you give it will be done as soon as possible - so that's what you need in your case.

Cheers,
Alex
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Wed Apr 01, 2020 3:47 pm

Hi Alex,

Thanks, but that's not what I'm asking about.
what you give it will be done as soon as possible
That's ok, but the order of execution of IOperations will follow the order of them being sent to your internal thread pool.

I need some IOperations, added at a later time, to execute before some added before them (of course if they are not already executing).


-žarko

User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Mon Apr 06, 2020 1:24 pm

Hello žarko,

I'm not sure that I understand your requirements correctly. You always can catch the Before Execture Operation event of some operation and then launch your own operation beforehand.

Cheers,
Alex
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Mon Apr 06, 2020 2:47 pm

Hi Alex,

I know what I ask for is probably not currently implemented :) But as we know "you never know".

Also, I'm not sure how to explain the idea/need in more details, so I'll try again:

When calling AsyncDo(some_IOperation) for multiple IOperations your internal code stores the "tasks" in a queue / thread pool.

Say I've sent 10 tasks to your internal queue via

Inst.AsyncDo(IOp_1)
Inst.AsyncDo(IOp_2)
...
Inst.AsyncDo(IOp_10)

At the moment your internal thread pool uses 3 threads (as stated by Vasyl in this topic)

For the sake of simplicity let's say that each task takes the same amount of time to be executed.

Meaning that "tasks" will be executed in the next order:

1. IOp_1 (thread 1)
2. IOp_2 (thread 2)
3. IOp_3 (thread 3)
4. IOp_4 (thread 1 or 2 or 3)
5. IOp_5 (thread 2 or 1 or 3)
6. IOp_6 (thread 3 or 1 or 2)
etc

Note how, for example, IOP_6 will be executed after all previous ([1,2,3]) have finished (or at least at the same time with the other tasks [4,5,6] in the group of 3).

What I need is to somehow say that IOP_9, for example, has the higher priority than other tasks (of course this makes sense only if IOP_9 is waiting to be executed).

This would mean that if we are at step (4) above, step 5 will not take task IOP_5 but the higher priority task IOP_9, then IOP_5 and the rest...

Hope this makes more sense.

-žarko

User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall  SOLVED

Post by Sasha - Tracker Dev Team » Tue Apr 07, 2020 6:44 am

Hello zarkogajic,

Well you will have to manage such an advanced behavior for yourself. Basically your IOperation interface, that you pass to the AyncDo, will have to signal you that something is being completed so that you can continue with your logic onward. It can do that via the https://sdkhelp.tracker-software.com/vi ... DoCallback that you can pass to the AsyncDo method. The OnStartOp method will be called when the TaskManager starts doing some of it's tasks and the OnFinishOp is being called when the operation has finished it's work. You should store some needed data in your custom IOperation interface implementation to distinguish between the operations and act accrodingly.
That is what can be done.

Cheers,
Alex
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

zarkogajic
User
Posts: 649
Joined: Thu Sep 05, 2019 12:35 pm

Re: On AsyncDo and ThreadSafeCall

Post by zarkogajic » Tue Apr 07, 2020 6:48 am

Hi Alex,

Yes, thanks, that's what I'm doing at the moment. I though: maybe, just maybe, a "priority" value already exists when using AsyncDo.


User avatar
Sasha - Tracker Dev Team
User
Posts: 4885
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: On AsyncDo and ThreadSafeCall

Post by Sasha - Tracker Dev Team » Tue Apr 07, 2020 6:49 am

:)
Join us at Google+:
https://plus.google.com/+PDFXChangeEditorTS
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ

Post Reply