Docs

BackgroundTask


Every callback that you define in HiseScript is being serialised and called on a single thread in order to avoid synchronisation issues and race conditions (a situation where two threads try to access the same resource). There is a priority system in place which makes sure that certain tasks cannot block other tasks (so eg. a control callback will be executed before a paint routine and if you recompile a script it will discard all pending callbacks for this script processor).

A notable exception is of course the realtime callbacks which are executed directly in the audio thread but since you should not allocate anything in there anyways, any possible race conditions between the scripting thread and the audio thread are not super critical.

However there are a few occasions where this model creates unwanted side effects: a really complex task that will take a lot of time might clog this system and prevent user interaction. In order to solve this, you can use this object to offload a heavyweight function to a separate thread while the scripting thread remains idle and responsive.

Be aware that at this point it is a highly experimental function and I would not advise using this without extensive testing of your use case as there might be many subtle issues that come from the multithreading of the function executions.

The prime use case for this object is when you are working with samples to create custom workflow tools.

In order to use it, create an object with Engine.createBackgroundTask() , and then give it a function to execute with callOnBackgroundThread() .


Class methods

callOnBackgroundThread

Call a function on the background thread.

BackgroundTask.callOnBackgroundThread(var backgroundTaskFunction)


This will start a new thread and call the function that you've passed in. The function must have a single parameter which will contain a reference to this object that you can use for status reporting / thread control.


getProgress

Get the progress for this task.

BackgroundTask.getProgress()



getProperty

Retrieve a property through a thread safe container.

BackgroundTask.getProperty(String id)



getStatusMessage

Returns the current status message.

BackgroundTask.getStatusMessage()



sendAbortSignal

Signal that this thread should exit.

BackgroundTask.sendAbortSignal(bool blockUntilStopped)


If the task is running, this will send a abort signal so that the next time you call shouldAbort() it will return false and gives you the option to cancel the task gracefully.

This can be called from any thread (but the most useful application is a control callback obviously). if blockUntilStopped is true, the function will wait until the thread has been stopped (in case you require that the thread has been terminated before proceeding).

setFinishCallback

Set a function that will be called when the task has started / stopped.

BackgroundTask.setFinishCallback(var newFinishCallback)


You can pass a function with two parameters here that will be executed when the thread starts and when it stops. This might be useful for notifying your UI that the task is in progress. Be aware that this function will be called on the scripting thread and might be executed at the same time as the actual task!

setForwardStatusToLoadingThread

Forward the state of this thread to the sample loading thread notification system.

BackgroundTask.setForwardStatusToLoadingThread(bool shouldForward)


There is another background thread in HISE that is used for preset / sample loading as well as for other heavyweight tasks. This offers a convenient notification system that you might already use in your project. In this case you can call this method with true and it will forward any status changes of this task. This includes:

Be aware that this only captures the notification system for the time the task is active but does not lock the real loading thread so if you spawn a task on the main loading thread (eg. loading a samplemap) while your custom task is active, it might create glitches and inconsistent notifications.

setProgress

Set a progress for this task.

BackgroundTask.setProgress(double p)



setProperty

Set a property to a thread safe container.

BackgroundTask.setProperty(String id, var value)



setStatusMessage

Sets a status message.

BackgroundTask.setStatusMessage(String m)



setTimeOut

Set timeout.

BackgroundTask.setTimeOut(int ms)


You can set a custom timeout period that the thread will wait until it will force-kill the task (which might leave things in a bad place). The default time is 500 milliseconds, but you can change this value if you need. The best way to get an estimate for how long you need the timeout is the period between calls to shouldAbort() . So if you have a task like this:

function myTask(thread)
{
	for(i = 0; i < 1000000; i++)
	{
		if(thread.shouldAbort())
			break;
			
		subFunctionThatTakes900MillisecondsPerRun();
	}
}

you should set the timeout to something like 1000ish milliseconds - including some headroom for computers that are slower obviously and I would rather suggest to break down the function in the loop into multiple parts and call shouldAbort() more often to avoid any freezing.

shouldAbort

Checks whether the task should be aborted (either because of recompilation or when you called abort().

BackgroundTask.shouldAbort()


This function should be called as often as possible to figure out whether the thread needs to be cancelled, which might happen because of two reasons:

  1. You have called sendAbortSignal()
  2. This object is being deleted (either because your app is terminated or the script is recompiled inside HISE)

If you're doing things in a loop it's highly advised to call it once per loop and the time between two calls to shouldAbort() must never exceed the thread timeout (in fact the execution will time out if you fail to do so which is a safe check that should prevent you from forgetting to call this).