Search code examples
c#unity-game-engineasynchronousasync-awaitunitywebrequest

How to add CancellationToken on Unity Web request?


I wrote the following code that successfully downloads a photo from the link. But I want to set a cancellationToken for the request that can be activated by pressing the x key. please guide me.

private async void GetImage()
{
    var request = UnityWebRequest.Get(requestURI);

    await RequestEnd(request);
    
    // add cancellation when I press any key..

    var date = request.downloadHandler.data;
    
    texture2D = new Texture2D(1, 1);
    
    texture2D.LoadImage(date);
}

private static async Task RequestEnd(UnityWebRequest request)
{
    request.SendWebRequest();
    Debug.Log("Request Send");

    while (!request.isDone) await Task.Yield();
}

Solution

  • You need a variable of type CancellationTokenSource.

    //inside the class
    private CancellationTokenSource downloadCancellationTokenSource;
    // inside GetImage.cs
    this.downloadCancellationTokenSource = new CancellationTokenSource();
    var token = this.downloadCancellationTokenSource.Token;
    await RequestEnd(request, token);
    

    And you add the token as a parameter to method RequestEnd():

    private static async Task RequestEnd(UnityWebRequest request, CancellationToken token)
    {
        request.SendWebRequest();
        Debug.Log("Request Send");
    
        while (!request.isDone) 
        {
           if (token.IsCancellationRequested)
           {
                Debug.Log("Task {0} cancelled");
                token.ThrowIfCancellationRequested();
           }
           await Task.Yield();
        }
    }
    

    Now, in an Update() method you can check for input "X" and cancel the async task:

    private void Update()
    {
      if(Input.GetKeyDown("X")
      {
            if (this.downloadCancellationTokenSource != null)
            {
                this.downloadCancellationTokenSource.Cancel();
                this.downloadCancellationTokenSource.Dispose();
                this.downloadCancellationTokenSource = null;
            }
      }
    }