# C#: Handles

Source: https://tweens.gd/csharp/api/handles/

Starting one definition returns a `TweenInstance<TTarget, TValue>` that controls that playback alone. The non-generic base class `TweenInstance` has every member but `Target` and `Value`, so handles of different types fit in one collection. [Await Completion](https://tweens.gd/csharp/playback/) introduces handles.

## Control

| Member | Type | Meaning |
| --- | --- | --- |
| [`Pause()`](https://tweens.gd/csharp/api/handles/#pause) | `void` | Hold playback, in addition to any [pause mode](https://tweens.gd/csharp/api/start/#tweenpausemode) |
| [`Resume()`](https://tweens.gd/csharp/api/handles/#resume) | `void` | Release that hold |
| [`IsPaused`](https://tweens.gd/csharp/api/handles/#ispaused) | `bool` | True while held by `Pause()`; settable |
| [`Cancel()`](https://tweens.gd/csharp/api/handles/#cancel) | `void` | Stop now and keep the latest value; does nothing once playback has ended |

## Status

| Member | Type | Meaning |
| --- | --- | --- |
| [`State`](https://tweens.gd/csharp/api/handles/#state) | `TweenState` | Where the timeline is; a paused handle keeps its state |
| [`Progress`](https://tweens.gd/csharp/api/handles/#progress) | `float` | Position in the current leg, from 0 to 1, before easing. It runs backward during a ping-pong return, and isn’t the share of all cycles completed |
| [`IsTerminal`](https://tweens.gd/csharp/api/handles/#isterminal) | `bool` | True once completed, cancelled, or faulted |
| [`IsSettled`](https://tweens.gd/csharp/api/handles/#issettled) | `bool` | True once the ending callbacks and cleanup have run |
| [`CompletionReason`](https://tweens.gd/csharp/api/handles/#completionreason) | `Reason?` | Why playback ended; `null` until it has |
| [`Error`](https://tweens.gd/csharp/api/handles/#error) | `Exception?` | The exception that faulted playback, if one did |
| [`Target`](https://tweens.gd/csharp/api/handles/#target) | `TTarget` | The animated object |
| [`Value`](https://tweens.gd/csharp/api/handles/#value) | `TValue` | The value captured at start, then the latest value written |

## Awaiting

| Member | Type | Meaning |
| --- | --- | --- |
| [`End`](https://tweens.gd/csharp/api/handles/#end) | `Task<Reason>` | Completes after the ending callbacks and cleanup. Any number of callers can await it, even after the end |
| [`AwaitDecommissionAsync(token)`](https://tweens.gd/csharp/api/handles/#awaitdecommissionasync-token) | `Task<Reason>` | The same wait, but `token` cancels only this wait and throws `OperationCanceledException`; playback continues |

## TweenState

| Member | Meaning |
| --- | --- |
| [`TweenState.Delayed`](https://tweens.gd/csharp/api/handles/#tweenstate-delayed) | Waiting out the delay |
| [`TweenState.Playing`](https://tweens.gd/csharp/api/handles/#tweenstate-playing) | Moving through a leg |
| [`TweenState.Interval`](https://tweens.gd/csharp/api/handles/#tweenstate-interval) | Holding at an endpoint, between legs or cycles |
| [`TweenState.Completed`](https://tweens.gd/csharp/api/handles/#tweenstate-completed) | Reached its natural end |
| [`TweenState.Cancelled`](https://tweens.gd/csharp/api/handles/#tweenstate-cancelled) | Stopped early |
| [`TweenState.Faulted`](https://tweens.gd/csharp/api/handles/#tweenstate-faulted) | Stopped by an exception; see `Error` |

## Reason

| Member | Meaning |
| --- | --- |
| [`Reason.Completed`](https://tweens.gd/csharp/api/handles/#reason-completed) | Reached its natural end |
| [`Reason.Cancelled`](https://tweens.gd/csharp/api/handles/#reason-cancelled) | `Cancel()` or `CancelTweens()` stopped it |
| [`Reason.TargetFreed`](https://tweens.gd/csharp/api/handles/#reason-targetfreed) | The target was queued for deletion, or found freed or disposed |
| [`Reason.OwnerExited`](https://tweens.gd/csharp/api/handles/#reason-ownerexited) | The owner left the scene tree, or a separate owner node was queued for deletion |
| [`Reason.RunnerDisposed`](https://tweens.gd/csharp/api/handles/#reason-runnerdisposed) | The runner, its tree, or a manual scheduler shut down |

Compare against `Completed` rather than a particular early reason: a node that owns its tween, as node targets do by default, reports `TargetFreed` after `QueueFree()` but `OwnerExited` after `Free()`, because `Free()` removes it from the tree before deleting it.

## Errors

-   An exception in interpolation, easing, a setter, or a callback faults the tween. `State` becomes `Faulted`, `Error` holds the exception, and awaiting `End` throws it; several failures are kept in an `AggregateException`.
-   Cleanup and `OnFinally` still run, and other tweens keep playing.
-   The scheduler reports the exception through `UnhandledException`, and the automatic runner forwards it to `GD.PushError`.
-   Invalid start arguments throw at the start call instead.

Catch errors in `async void` callbacks

`_Ready` and other Godot callbacks are often `async void`. Wrap awaited sequences in `try`/`catch`, or a faulted tween’s exception is lost.

## Threading

-   Create and control tweens, and await `End`, on Godot’s main thread. `End` completes there, so ordinary Godot async code keeps its synchronization context.
-   Don’t block with `.Wait()` or `.Result`, and keep engine access out of `Task.Run` and `ConfigureAwait(false)`.
-   tweens.gd has no coroutine API; use Godot’s `ToSignal` for unrelated engine signals.
