Indicators are considered UI code?

Hello

I am experimenting with the THREADSLEEP function:
https://www.amibroker.com/guide/afl/threadsleep.html

The documentation states:
Works only from NON-UI threads. When called from UI thread the function does NOTHING and returns immediatelly.

The following code is from a very simple INDICATOR. Here the Threadsleep does work (I do see a delay). I thought this is UI code/thread. Could somebody tell me what I am doing wrong please?

SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
Plot( C, "Close", ParamColor( "Color", colorDefault ), styleNoTitle | ParamStyle( "Style" ) | GetPriceStyle() );

ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);
ThreadSleep(100);

Indicators run in worker (non-UI) threads. UI thread is only one, the main one responsible for UI. And do not abuse ThreadSleep(). It is not meant to delay execution for seconds. It is meant only to introduce single millisecond delays.

1 Like

Hi

Thank you very much for the answer.

Is this thread something I can code and affect? I am asking this just for educational purposes....

@bobptz just out of curiosity. Why did you even think of using ThreadSleep(100) for delaying the execution of the code? If you for example use:

for(i=1; i<=10; i++) ThreadSleep(100); // Do not use it!

... it makes the whole indicator unresponsive (in this case) for one second. So it's a very bad solution. There are many ways of executing some parts of the code conditionally or every n seconds or delaying the execution for some time, without making the indicator sluggish or not responsive ...

1 Like

Hi @Milosz

I wanted to write a simple piece of code that anybody can understand. The original code where I use Threadsleep is more than 2500 lines, divided in 3 files.

One instance that I use it from the original code is:

while( DateTimeDiff( LastValidBarDateTime, next_upTF_DateTime ) >= 0 )
            {
                _MYTRACE( part_diag_filename, "ThreadSleep( 10 ).           This TF LastValidBar = " + DateTimeToStr( LastValidBarDateTime, 3 ) +
                          ", upTF LastValidBar = " + DateTimeToStr( upTF_LastValidBarDateTime, 3 ) +
                          ", upTF next bar = " + DateTimeToStr( next_upTF_DateTime, 3 ) );
                ThreadSleep( 10 );

                upTF_LastValidBarDateTime = StaticVarGet( upTFstr + "LastValidBarDateTime" );
                next_upTF_DateTime = DateTimeAdd( upTF_LastValidBarDateTime, upTF, in1second );
            }

I was afraid that if I gave the original code and asked if this is considered UI code, people would not be able to answer.

OK thanks for the info. I'm not sure what is the wider context of your whole code, so my suggestions might not be relevant, but I simply wanted to encourage you to replace (in most cases) using ThreadSleep() which freezes the execution of the whole code with some alternatives which don't make the whole code unresponsive. For instance, you can repeat or delay executing some parts of the code using Status("redrawaction") and/or GetPerformanceCounter(). If you need to wait 0.5 or 3 or 10 seconds, the code will still be responsive during the waiting period. Take a look at some examples:

1 Like

@Milosz

These are great examples. Thank you.

In my case, I need to delay execution of one script until another one produces results.

So don't hold the execution of the whole code. There's really no need to do that! Just check every n seconds (or even fraction of a second) if some condition is met and only then run another part of the code. To run another script conditionally, you can use ShellExecute(). During the waiting period, your code will still be responsive.

Alternatively you can also use Batch window ( Execute And Wait) or OLE to sequence tasks and make one formula execute only if the previous one has finished.

https://www.amibroker.com/guide/h_batch.html

1 Like

@Milosz

This is not a problem for me right now, thank you.

Would you know what is a UI thread that threadsleep() would have no effect, as Tomasz said? I am still wondering.

UI thread is the main application thread, the one that is started by Windows itself when application starts. It is main application thread responsible for handling UI, i.e. menu, buttons, dialogs, mouse clicks, etc. As an end-user you don't have direct programmatic access to it (even Gui* functions don't live in UI thread and only 'communictate' with UI thread).

The AFL can be run in worker (non-UI) threads and in main UI thread. There are some cases when AFL is run from main UI thread (for example when you press "Reset all" button in the Parameters)
or when using OLD Automatic analysis. In such cases ThreadSleep does nothing to prevent locking UI (since sleeping UI thread is HUGE no-no as it blocks entire app).

"Normal" applications like say Notepad or Calculator, have only one thread, the main UI thread.

Only multi-threaded applications have non-UI threads.

Thank you for the explanations Tomasz.