kenshima
kenshima

Reputation: 583

How to cancel Google Cloud StorageClient UploadObjectAsync?

I just wanted to find out if its possible to cancel the GCP Storage client UploadObjectAsync?

basically I'm running a winforms app with a backgroundworker that calls UploadObjectAsync from backgroundWorker1_DoWork. I thought it would be as simple as calling backgroundworker.CancelAsync() but now I realise I need to cancel the upload as well. Since its an asynchronous upload is there a way to maybe set a flag that cancels the request?

My code to cancel backgroundworker

private void cancelLoadBttn_Click(object sender, EventArgs e){
    // Cancel the asynchronous operation.
    this.backgroundWorker1.CancelAsync();

    setResultLabelText("Upload Cancelled");
    // Disable the Cancel button.
    cancelLoadBttn.Enabled = false;
}

backgroundworker1_doWork

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e, string projectID, string bucketName, GoogleCredential credentials, string filePath)
{
    // Get the BackgroundWorker that raised this event.
    BackgroundWorker worker = sender as BackgroundWorker;
    /
    if (!e.Cancel) {
        UploadAsync(projectID, bucketName, credentials, filePath);
    }
    

}

UploadAsync

public async void UploadAsync(string projectID, string bucketName, GoogleCredential credentials, string filePath,string objectName = null)
{
    var newObject = new Google.Apis.Storage.v1.Data.Object
    {
        Bucket = bucketName,
        Name = System.IO.Path.GetFileNameWithoutExtension(filePath),
        ContentType = "text/csv"
    };

    // Instantiates a client.
    using (var storageClient = Google.Cloud.Storage.V1.StorageClient.Create(credentials))
    {
        if (!backgroundWorker1.CancellationPending)
        {
            try
            {
                // Open the image file filestream
                using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open))
                {
                    setMax((int)fileStream.Length);

                    // set minimum chunksize just to see progress updating
                    var uploadObjectOptions = new Google.Cloud.Storage.V1.UploadObjectOptions
                    {
                        ChunkSize = Google.Cloud.Storage.V1.UploadObjectOptions.MinimumChunkSize
                    };

                    // Hook up the progress callback
                    var progressReporter = new Progress<Google.Apis.Upload.IUploadProgress>(OnUploadProgress);

                    objectName = objectName ?? Path.GetFileName(filePath);
                    
                    /*storageClient.UploadObject*/
                    await storageClient.UploadObjectAsync(
                        bucketName,
                        objectName,
                        null,
                        fileStream,
                        uploadObjectOptions,
                        progress: progressReporter);

                    Console.WriteLine($"Uploaded { objectName}.");

                    fileStream.Close();
                }

            }
            catch (Google.GoogleApiException e)
                when (e.Error.Code == 409)
            {
                // When creating the bucket - The bucket already exists.  That's fine.
                Console.WriteLine(e.Error.Message);
            }
            catch (Exception e)
            {
                // other exception
                Console.WriteLine(e.Message);
            }
        }
        
        
    }
}

Upvotes: 2

Views: 696

Answers (1)

Rafael Lemos
Rafael Lemos

Reputation: 5829

As you can see in the documentation for UploadObjectAsync, the method accepts a CancellationToken as a parameter, which you are not using in your code and if you want to cancel the task that is generated by that method you need the token.

I have found a .Net documentation on how to implement cancellation tokens in tasks, which is exactly what you need to do in this case.

Basically what you need to implement is to create a CancellationToken as mentioned in the example of the .Net documentation, use it as a parameter of the UploadObjectAsync method which will return you a Task<Object> and when you want to cancel the upload, cancel the tokenSource of the CancellationToken, also explained in the documentation.

Upvotes: 1

Related Questions