Last active
November 4, 2024 23:57
-
-
Save baudii/ce23d68bc6670b2cff8ca1e73e4d63ef to your computer and use it in GitHub Desktop.
Simple extension method that converts Unity's AsyncOperation into a Task to use it with await. Unlike extending GetAwaiter(), this implementation supports cancellation tokens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static Task AsTask(this AsyncOperation asyncOperation, CancellationToken cancellationToken = default) | |
| { | |
| cancellationToken.ThrowIfCancellationRequested(); | |
| if (asyncOperation == null) | |
| throw new ArgumentNullException(nameof(asyncOperation), "Provided async operation is null"); | |
| if (asyncOperation.isDone) | |
| return Task.CompletedTask; | |
| var tcs = new TaskCompletionSource<object>(); | |
| IDisposable registration = null; | |
| if (cancellationToken.CanBeCanceled) | |
| registration = cancellationToken.Register(OnCanceled); | |
| asyncOperation.completed += OnCompleted; | |
| return tcs.Task; | |
| void OnCompleted(AsyncOperation op) | |
| { | |
| registration?.Dispose(); | |
| asyncOperation.completed -= OnCompleted; | |
| tcs.TrySetResult(null); | |
| } | |
| void OnCanceled() | |
| { | |
| registration.Dispose(); | |
| asyncOperation.completed -= OnCompleted; | |
| tcs.TrySetCanceled(cancellationToken); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Example 1: | |
| AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName); | |
| await asyncOperation.AsTask(cancellationToken); | |
| // Example 2: | |
| AsyncOperation asyncOperation = Resources.LoadAsync<GameObject>(resourcePath); | |
| await asyncOperation.AsTask(); | |
| // Example 3: | |
| var asyncOperation = webRequest.SendWebRequest(); | |
| await asyncOperation.AsTask(timeoutMilliseconds); | |
| // Example 4: | |
| AssetBundleRequest asyncOperation = bundle.LoadAssetAsync<GameObject>(assetName); | |
| await asyncOperation.AsTask(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment