# Async operation handling Several methods from the `Addressables` API return an `AsyncOperationHandle` struct. The main purpose of this handle is to allow access to the status and result of an operation. The result of the operation is valid until you call `Addressables.Release` or `Addressables.ReleaseInstance` with the operation (for more information on releasing assets, see documentation on [memory management](MemoryManagement.md). When the operation completes, the `AsyncOperationHandle.Status` property is either `AsyncOperationStatus.Succeeded` or `AsyncOperationStatus.Failed`. If successful, you can access the result through the `AsyncOperationHandle.Result` property. You can either check the operation status periodically, or register for a completed callback using the `AsyncOperationHandle.Complete` event. When you no longer need the asset provided by a returned `AsyncOperationHandle` struct, you should [release](MemoryManagement.md) it using the `Addressables.Release` method. ### Type vs typeless handles Most `Addressables` API methods return a generic `AsyncOperationHandle`struct, allowing type safety for the `AsyncOperationHandle.Completed` event, and for the `AsyncOperationHandle.Result` object. There is also a non-generic `AsyncOperationHandle` struct, and you can convert between the two handles as desired. Note that a runtime exception occurs if you attempt to cast a non-generic handle to a generic handle of an incorrect type. For example: ``` AsyncOperationHandle textureHandle = Addressables.LoadAssetAsync("mytexture"); // Convert the AsyncOperationHandle to an AsyncOperationHandle: AsyncOperationHandle nonGenericHandle = textureHandle; // Convert the AsyncOperationHandle to an AsyncOperationHandle: AsyncOperationHandle textureHandle2 = nonGenericHandle.Convert(); // This will throw and exception because Texture2D is required: AsyncOperationHandle textureHandle3 = nonGenericHandle.Convert(); ``` ### AsyncOperationHandle use case examples Register a listener for completion events using the `AsyncOperationHandle.Completed` callback: ``` private void TextureHandle_Completed(AsyncOperationHandle handle) { if (handle.Status == AsyncOperationStatus.Succeeded) { Texture2D result = handle.Result; // The texture is ready for use. } } void Start() { AsyncOperationHandle textureHandle = Addressables.LoadAsset("mytexture"); textureHandle.Completed += TextureHandle_Completed; } ``` `AsyncOperationHandle` implements `IEnumerator` so it can be yielded in coroutines: ``` public IEnumerator Start() { AsyncOperationHandle handle = Addressables.LoadAssetAsync("mytexture"); yield return handle; if (handle.Status == AsyncOperationStatus.Succeeded) { Texture2D texture = handle.Result; // The texture is ready for use. // ... // Release the asset after its use: Addressables.Release(handle); } } ``` Addressables also supports asynchronous `await` through the `AsyncOperationHandle.Task` property: ``` public async Start() { AsyncOperationHandle handle = Addressables.LoadAssetAsync("mytexture"); await handle.Task; // The task is complete. Be sure to check the Status is succeessful before storing the Result. } ``` #### Please Note: Loading scenes with `SceneManager.LoadSceneAsync` with `allowSceneActivation` set to false or using `Addressables.LoadSceneAsync` and passing in false for the `activateOnLoad` parameter can lead to subsequent async operations being blocked and unable to complete. Please checkout the `allowSceneActivation` documentation here: https://docs.unity3d.com/ScriptReference/AsyncOperation-allowSceneActivation.html