Skip to content

Instantly share code, notes, and snippets.

@krzys-h
Created July 20, 2018 22:47
Show Gist options
  • Save krzys-h/9062552e33dd7bd7fe4a6c12db109a1a to your computer and use it in GitHub Desktop.
Save krzys-h/9062552e33dd7bd7fe4a6c12db109a1a to your computer and use it in GitHub Desktop.
[Unity] Use UnityWebRequest with async/await
public class UnityWebRequestAwaiter : INotifyCompletion
{
private UnityWebRequestAsyncOperation asyncOp;
private Action continuation;
public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
{
this.asyncOp = asyncOp;
asyncOp.completed += OnRequestCompleted;
}
public bool IsCompleted { get { return asyncOp.isDone; } }
public void GetResult() { }
public void OnCompleted(Action continuation)
{
this.continuation = continuation;
}
private void OnRequestCompleted(AsyncOperation obj)
{
continuation();
}
}
public static class ExtensionMethods
{
public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
{
return new UnityWebRequestAwaiter(asyncOp);
}
}
/*
// Usage example:
UnityWebRequest www = new UnityWebRequest();
// ...
await www.SendWebRequest();
Debug.Log(req.downloadHandler.text);
*/
@streeter12
Copy link

streeter12 commented Aug 20, 2021

if continuation is null, it's possible it could be called while null, so OnRequestComplete should accommodate a nullcheck.

It is no possible, because subscription made after set of parameter in OnCompleted.

this.continuation = continuation;
asyncOp.completed += OnRequestCompleted;

After performance and allocation`s tests we made this minimalistic version:

[ DebuggerNonUserCode ]
    public readonly struct AsyncOperationAwaiter : INotifyCompletion
    {
        private readonly AsyncOperation _asyncOperation;
        public bool IsCompleted => _asyncOperation.isDone;

        public AsyncOperationAwaiter( AsyncOperation asyncOperation ) => _asyncOperation = asyncOperation;

        public void OnCompleted( Action continuation ) => _asyncOperation.completed += _ => continuation();

        public void GetResult() { }
    }

 [ DebuggerNonUserCode ]
    public readonly struct UnityWebRequestAwaiter : INotifyCompletion
    {
        private readonly UnityWebRequestAsyncOperation _asyncOperation;

        public bool IsCompleted => _asyncOperation.isDone;

        public UnityWebRequestAwaiter( UnityWebRequestAsyncOperation asyncOperation ) => _asyncOperation = asyncOperation;

        public void OnCompleted( Action continuation ) => _asyncOperation.completed += _ => continuation();

        public UnityWebRequest GetResult() => _asyncOperation.webRequest;
    }

This code and other for async operations in unity could be found in https://github.com/CrazyPandaLimited/SimplePromises

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment