The Lock component lets you control how Studio uses threads in automation execution. Threads are a resource within the operating system and only a limited number are available at a time. Using too many threads simultaneously can cause a CPU thrashing.
Thrashing occurs when there are too many threads competing for CPU time. Thrashing slows the entire operating system. Client operating systems such as Windows were primarily designed to handle user input. Typically, a user only interacts with one application or thread at a time. Studio, however, lets you automate several applications simultaneously. While this is powerful, it can also degrade performance if the interaction amongst applications is not properly managed.
Studio projects and threads
When Studio starts a project, the first thread it creates is the user interface thread. The user interface thread is responsible for displaying any Windows forms in the project. Typically the user interface thread is either painting the user interface to the screen or waiting for user input. When the user interacts with a Windows form or its child controls, Windows sends messages describing the user activity to the user interface thread. The user interface processes hundreds of messages every second. In response to these messages, the user interface thread raises Windows forms events such as Click, KeyPressed, or TextChanged. All Windows forms events are raised synchronously and execute on the user interface thread.
Studio automations and user interface thread
Since the user interface thread is also responsible for painting to the screen, any long-running activity that occurs on the user interface thread can block both painting and message processing. This gives the user the impression that the user interface is not responding. To avoid this, all automations that are triggered by a Windows form event should execute on an asynchronous event link to release the user interface thread before it interacts with any adapter controls or non-Windows forms components, such as web services or data access and queries.
When Runtime starts a project's adapter, the adapter creates a thread to monitor the target application. Studio injects code within the target application to forward messages from the target application to the monitor thread. In response to some messages, the monitor thread may initiate matching to identify adapter controls. In response to other messages, such as user input, the monitor thread raises adapter control events such as Click, KeyPressed, or TextChanged. The monitor thread can raise adapter control events synchronously or asynchronously.
Synchronous events are blocking events – they prevent a thread from executing. When an automation is triggered by a synchronous event, the target application will block until the automation completes or an asynchronous link executes. Most synchronous events are cancelable. Within an automation, you can choose to cancel the event (so that it is not raised within the target application). Synchronous events are always suffixed with "ing," such as Clicking and DoubleClicking.
Controlling threads with the Lock component
Using the Lock component, you can specify that automation execution occurs on a single thread. Events which try to execute the same automation logic are blocked until the locked thread is released. Using a Lock component makes sure the execution of specific automation logic proceeds to without interruption by any other events which may attempt to execute the same automation logic.
Use the Lock.RequestLock method to restrict execution to a specific thread, then call the Lock.ReleaseLock method to free the thread lock. Note that only one thread at a time can be locked. The thread, or execution flow, can be locked multiple times, however, for every lock request, a lock release must be issued.
If additional calls to the Lock.RequestLock method occur while a the Lock component has an active thread lock, such as before the Lock.ReleaseLock occurs, the requests are queued. When the Lock.ReleaseLock method is called, the Lock component releases the lock on the current thread and assigns a lock to the next request in the queue. Use the Lock.RequestLock method's Timeout parameter to set the amount of time to elapse while waiting for a locked thread to become available (Lock.ReleaseLock executed). If the thread is not released before the expiration of the timeout interval, the pending Lock.RequestLock expires and falls out of the lock request queue.
|IsLocked||This property returns True when the Lock.RequestLock method has been executed and a thread is currently locked.|
|IsRequestPending||When the Lock.RequestLock method has been called and the current locked thread has not been released (see Lock.RequestLock method), the IsRequestPending property indicates whether additional requests to lock the same execution thread have been called (Lock.RequestLock) and are waiting to lock the execution thread. Studio queues all lock requests received while an execution thread is currently locked. If there are queued requests, this property returns True. When the Lock.RequestLock method is called, the next request in the queue is able to lock the execution. Note that a queued lock request remains in the queue until the request's timeout expires.|
|PendingRequests||When the Lock.RequestLock method has been called and the lock has not been released (see the Lock.ReleaseLock method), this property gets the number of additional requests in queue to lock the execution thread. As the locks are released or the lock requests time out, the PendingRequests is decremented.|
Use this method to maintain execution on a single thread, blocking execution from any other control. After the Lock.RequestLock method occurs, the execution thread is blocked until the Lock.ReleaseLock method is called. Therefore, when you use this method you must also use the Lock.ReleaseLock method at the end of the execution path or the automation will cease processing.
Additional requests to lock an execution thread can occur while a thread is locked. These requests are queued until the current thread lock has been released (using the Lock.ReleaseLock method). Use the Lock.RequestLock timeout (seconds) parameter to specify the amount of time a lock request remains in queue waiting for the current lock to be released. After the timeout interval, the lock request falls out of the queue and is not executed.
The Lock.RequestLock method returns a Boolean result. If the Lock.RequestLock method succeeds in establishing a lock on the execution thread, the result is True. If a thread lock is unable to be established, the result is False.
|ReleaseLock||Use this method to release a lock placed on a thread by the Lock.RequestLock method. The method returns True when the lock has been released.||None||Boolean|