Class
Task
Warning
This item was deprecated in version 2019r2. Please use Thread as a replacement.
Description
Task is a Thread subclass that has a mechanism for allow user interface updates. Task is not part of the Xojo Framework.
Properties
Name |
Type |
Read-Only |
Shared |
---|---|---|---|
✓ |
✓ |
||
✓ |
|||
✓ |
Methods
Name |
Parameters |
Returns |
Shared |
---|---|---|---|
data As Dictionary |
|||
MilliSeconds As Integer, [WakeEarly As Boolean] |
|||
milliseconds As Integer |
✓ |
||
✓ |
Events
Name |
Parameters |
Returns |
---|---|---|
data() As Dictionary |
Property descriptions
Task.Current
Current As Thread
Returns the thread that was executing at the moment this property was read.
This property is read-only.
This property is shared.
This property is Nil when accessed from the main thread.
Task.DebugIdentifier
DebugIdentifier As String
Identifer which will show up in the debugger's thread popup.
Task.Priority
Priority As Integer
Gets and sets the relative priority of the thread.
The Priority can be changed while a Thread is running.
The application's main thread has a priority of 5 and this is also the default value of any programmatically created threads. If you don't modify this value, your application will behave normally, in the sense that all the threads will share the CPU's resources equally.
Increasing the value of Priority above 5 gives that thread more processing cycles than other threads. Doubling the value of Priority will double the number of processing cycles the thread gets. A thread with a Priority of 1 will get one-fifth the processing cycles as the main thread. The range is 1 to 2^31-1, but very high values of Priority will make it difficult for other threads to run at all. The value of Priority changes the way in which threads get processing cycles only if their values are not all equal. You can use the following class constants to assign to Priority or to compare its value:
Value |
Description |
---|---|
1 |
LowestPriority |
5 |
NormalPriority |
10 |
HighPriority |
You do not need to use these constants; you can use any legal integer value instead.
This example lowers the priority of the thread prior to calling its Run method.
Thread1.Priority = Thread.LowestPriority
Thread1.Run
Task.StackSize
StackSize As Integer
The size of the stack, in bytes.
The StackSize can only be set when the thread is not running. The default stack size is 512KB on macOS and Linux and 1MB on Windows. A StackSize of zero indicates the default is used.
There is generally little reason to change this. Each stack frame only need to contain information about the parameters, local variables and return address for a method call. This does not include memory needed for objects. It would take a significant amount of local variables or parameters with method calls that are 100s of levels deep in order to exhaust the stack space.
Thread1.StackSize = 96000
Task.ThreadID
ThreadID As Integer
ID of the thread, assigned at runtime.
This property is read-only.
Note: ThreadID will be non-zero only when the Thread is running.
This example reports the ThreadID only if the thread is running.
If LongProcessThread1.State <> Thread.NotRunning Then
MessageBox(LongProcessThread1.ThreadID.ToString)
Else
MessageBox("The thread is not running!")
End If
Task.ThreadState
ThreadState As Thread.ThreadStates
Indicates the state of the thread.
This property is read-only.
A thread can be in one of five states. See Thread for details.
This window method checks the State of the thread and displays a message in a TextField on the form. The parameter is:
State As Thread.ThreadStates
Select Case State
Case Thread.ThreadStates.Running
TextField1.Text = "Running"
Case Thread.ThreadStates.Waiting
TextField1.Text = "Waiting"
Case Thread.ThreadStates.Sleeping
TextField1.Text = "Sleeping"
Case Thread.ThreadStates.Paused
TextField1.Text = "Paused"
Case Thread.ThreadStates.NotRunning
TextField1.Text = "Not Running"
End Select
Method descriptions
Task.AddUserInterfaceUpdate
AddUserInterfaceUpdate(data As Dictionary)
Triggers the UserInterfaceUpdate event so you can update your user interface from the thread.
Task.Pause
Pause
Puts the thread in a paused state. Every call to Pause must be matched by a call to Resume.
The thread will not be allocated any processing cycles, regardless of its assigned Priority. It is “asleep.” To wake it up, call the Resume method. If the thread is executing when you call Pause, it will immediately cause a context switch.
This example calls Pause, followed by a call to Resume after other code has executed.
LongProcessThread1.Pause
' do something else here...
LongProcessThread1.Resume
Task.Resume
Resume
Wakes up a thread that was paused because of a call to Thread or is sleeping because of a call to Thread. Every call to Pause must be matched by a call to Resume.
When you call Resume, the thread reacquires its ability to receive processing cycles according to its value of Priority. Calling Resume will not cause a context switch to take place, that is, a switch to the next thread in the queue.
LongProcessThread1.Resume
Task.Sleep
Sleep(MilliSeconds As Integer, [WakeEarly As Boolean])
Puts the thread to sleep for the specified amount of time.
By default, WakeEarly is False. If it is not set to True, the thread will be put to sleep for the full amount of time specified by MilliSeconds. If you set WakeEarly to True, the thread can be resumed early. It will wake up early if there are no other threads able to execute.
LongProcessThread1.Sleep(300, True)
Task.SleepCurrent
SleepCurrent(milliseconds As Integer)
Sleeps the currently executing thread for the specified number of milliseconds.
This method is shared.
If the currently executing thread is the main thread, it will sleep like any other thread would.
Task.Start
Start
Starts the thread's Run event handler.
Task.Stop
Stop
Stops the specified thread.
Internally, this method will cause your thread's stack to unwind, destructors for local objects to be called, and so forth. It's a graceful exit which can cause code to execute. It may also cause context switches.
Note
A thread should not stop itself. Instead, just return from the Run event handler to allow the thread to end.
This example, which is in the Action event of a button, stops the thread.
LongProcessThread1.stop
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
Task.UpdateUI
UpdateUI
Calls the UpdateUI event handler where you can update the user interface. Pass in necessary arguments as a Pair.
In the Run method of the Task subclass, call the UpdateUI method to supply arguments that will be sent to the UpdateUI event handler where you can directly update the user interface.
This code updates a ProgressBar passing in the value to use as a Pair:
Dim progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
' Do nothing for 1/4 second or so so folks can see the actual progress
Dim waitUntil As Integer = Ticks + 15
While Ticks < waitUntil
Wend
' Call UpdateUI with any parameters you need. This calls the UpdateUI event handler
' where you can directly access any UI controls on the Window.
' This specifies simple parameters using a Pair
' You can also pass values using a Dictionary
Me.UpdateUI("UIProgress":progressValue)
Wend
This code updates a ProgressBar passing in the value to use as a Dictionary:
Dim progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
' Do nothing for 1/4 second or so so folks can see the actual progress
Dim waitUntil As Integer = Ticks + 15
While Ticks < waitUntil
Wend
' Call UpdateUI with any parameters you need. This calls the UpdateUI event handler
' where you can directly access any UI controls on the Window.
Dim d As New Dictionary
d.Value("UIProgress") = progressValue
Me.UpdateUI(d)
Wend
Task.YieldToNext
YieldToNext
Causes the current thread to yield its time to the next thread.
This method is shared.
This causes the Thread Scheduler to yield the currently executing thread's processing time to the next Thread in the queue that is awaiting processing cycles. It is possible for the next Thread to be the currently executing Thread.
Event descriptions
Task.Run
Run
The Run method has been called. The threaded code is placed in this event handler. Methods called from here also run in the thread.
MacOS apps cannot access the user interface from within a thread. Doing so raises a ThreadAccessingUIException. Instead, use the Thread method in conjunction with the Thread event. See the Thread event for an example.
Task.UpdateUI
UpdateUI
In this event handler, you can do user interface updates. This is called by calling the UpdateUI method.
You can supply a variety of values (as a Dictionary that you can use to determine what to update and how to update it.
This code checks for passed value to use to update a ProgressBar on the Window:
If args.HasKey("UIProgress") Then
UIProgress.Value = args.Value("UIProgress").IntegerValue
End If
Task.UserInterfaceUpdate
UserInterfaceUpdate(data() As Dictionary)
Used to update your app's user interface.
Apps cannot access the user interface from within the Run event of a thread. Doing so raises a ThreadAccessingUIException. Instead, use the UserInterfaceUpdate event to update your user interface. It can be triggered by calling the AddUserInterfaceUpdate method from within the Run event.
Each call to AddUserInterfaceUpdate in the Run event, adds the values passed to an array that is then passed to the UserInterfaceUpdate event (the data() parameter above). This allows you to process all of the calls to AddUserInterfaceUpdate or just the most recent one. For example, if your thread was reading a series of files and you wished to add the name of each file read to a ListBox, you'd want to read each row of the data() array passed to this event. However, if you instead were only displaying a ProgressBar and wanted to show how far you'd gotten through reading all the files, it would be more efficient to read the last item of the data() array passed to this event and then update your ProgressBar control rather than iterate through all of the items in the data() array.
This code (in the UserInterfaceUpdate event) updates a ProgressBar (called UIProgress) on a Window:
For Each update As Dictionary In data
If update.HasKey("UIProgress") Then
UIProgress.Value = update.Value("UIProgress").IntegerValue
End If
Next
The Data parameter is an array of Dictionaries containing information supplied by the AddUserInterfaceUpdate method that can be used to update the UI.
The Run method contains the code that runs in the thread and calls AddUserInterfaceUpdate with any necessary information:
Var progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
//Your processing code goes here. For the sake of this example
//we've added a dummy loop below so you can see the progress bar update.
' Do nothing for 1/4 second
Var waitUntil As Integer = System.Ticks + 15
While System.Ticks < waitUntil
Wend
' Call AddUserInterfaceUpdate with any parameters you need. This calls the UserInterfaceUpdate event handler
' where you can directly access any UI controls on the Window.
' This specifies simple parameters using a Pair
' You can also pass values using a Dictionary
Me.AddUserInterfaceUpdate("UIProgress":progressValue)
Wend
Notes
Task is not part of the Xojo framework, but because UI access from a thread raises a ThreadAccessingUIException, it is important enough to warrant its own API entry.
If you instantiate a Task in a local variable, keep in mind that the Task instance only remains available as long as both the variable is in scope and the thread is running. If the variable goes out of scope then it is possible the thread will complete but not be able to process its UpdateUI event because it is no longer available. To avoid this you should instead create your instance as a property so that it remains available longer or add a Sleep call of sufficient time to the end of the thread so that the UpdateUI event has enough time to run.
Sample code
To use Task, add both TaskEvent and Task to your project and then drag Task onto a Layout Editor.
In the UpdateUI event handler, you add put the code that accessing the UI. This code updates a ProgressBar (called UIProgress) on a Window:
If args.HasKey("UIProgress") Then
UIProgress.Value = args.Value("UIProgress").IntegerValue
End If
The args parameter is a Dictionary containing information supplied by the UpdateUI method that can be used to update the UI.
The Run method contains the code that runs in the thread and calls UpdateUI with any necessary information:
Dim progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
' Do nothing for 1/4 second or so so folks can see the actual progress
Dim waitUntil As Integer = Ticks + 15
While Ticks < waitUntil
Wend
' Call UpdateUI with any parameters you need. This calls the UpdateUI event handler
' where you can directly access any UI controls on the Window.
' This specifies simple parameters using a Pair
' You can also pass values using a Dictionary
Me.UpdateUI("UIProgress":progressValue)
Wend
Compatibility
All project types on all supported operating systems.