Upload & Download File to Azure Blob Storage Asynchronously and Cancel Async With VB .Net


Asynchronous technique becomes important when dealing with cloud resources or accessing object in long distance network route.
Latency could blocking the application UI for sometimes if there are any big resources processed synchronously.

Microsoft Windows Azure Storage is one of best options to store Blob, File, Queue, Document Table and also SQL databases.
Other well known and could considered as best cloud storage options are Amazon S3, Google but this post will be focused on Azure since the source code is built for Azure storage.

The source code in this post is available for download at below url:
WinCloudAsyncAwait SourceCode

The demonstration application is a Visual Basic .Net WinForm. This app upload and download image file from/to Azure Blob storage asynchronously.
It also has Cancel to Async thread and List of uploaded files. Below is the Form’s design


Upload Async & Download Async buttons upload & download image respectively. Cancel button cancels every process in Form i.e upload, download, refresh list.
Picture Box shows image. Delay in seconds textbox specifies how many seconds in the every process should be delayed for demonstration purposes so user can have a chance to click cancel button and see what happens.
This example use Azure storage emulator to store images as Blob.

VB .Net Project Step by Step

  1. Create a VB .Net WinForm project
  2. Add reference to WindowsAzure.Storage. You might need to install the library using Nuget Package Manager
  3. Create a Form like above Form’s Design picture
  4. Open app.config and edit it:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup>
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
        </startup>
        <appSettings>
          <add key="StorageConnectionString" value="UseDevelopmentStorage=true" />
        </appSettings>
    </configuration>
    

    Since we are using Azure storage emulator then the connection string is just UseDevelopmentStorage=true

  5. Create a class to encapsulate upload, download and listing files
    Code to create blob container asynchronously:

    Private Async Function CreateContainer(ByVal cancelToken As CancellationToken) As Task
    Try
    	Dim storAcc As CloudStorageAccount = CloudStorageAccount.Parse(StorageConnStr)
    	Dim blobClient As CloudBlobClient = storAcc.CreateCloudBlobClient()
    	container = blobClient.GetContainerReference(containerName)
    	Await container.CreateIfNotExistsAsync(cancelToken)
    
    	Dim blobContPermission As New BlobContainerPermissions()
    	blobContPermission.PublicAccess = BlobContainerPublicAccessType.Container
    
    	container.SetPermissions(blobContPermission)
    Catch ex As OperationCanceledException
    	Throw New OperationCanceledException("Create container canceled")
    End Try
    
    End Function
    

    Code to upload a file asynchronously:

    Public Async Function UploadAsync(ByVal path As String, ByVal cancelToken As CancellationToken) As Task
    Try
    	Await CreateContainer(cancelToken)
    	Dim blockBlob As CloudBlockBlob = container.GetBlockBlobReference(System.IO.Path.GetFileName(path))
    	Await blockBlob.UploadFromFileAsync(path, cancelToken)
    
    Catch ex As OperationCanceledException
    
    	Throw New OperationCanceledException("UploadAsync canceled")
    End Try
    End Function
    

    Refer to previous post for Upload blob to Azure Storage at this url:
    https://gugiaji.wordpress.com/2016/04/27/upload-file-to-azure-cloud-storage-via-asp-net-web-app/

    Below is a Code to download and list files from Azure

    Public Async Function DownloadAsync(ByVal imgName As String, ByVal cancelToken As CancellationToken) As Task
    Try
    	Await CreateContainer(cancelToken)
    	Dim blockBlob As CloudBlockBlob = container.GetBlockBlobReference(imgName)
    	Dim targetStream As System.IO.FileStream = System.IO.File.OpenWrite(My.Application.Info.DirectoryPath & "\" & imgName)
    
    	Await blockBlob.DownloadToStreamAsync(targetStream, cancelToken)
    
    	targetStream.Close()
    Catch ex As OperationCanceledException
    
    	Throw New OperationCanceledException("DownloadAsync canceled")
    End Try
    End Function
    
    Public Async Function ListFilesAsync(ByVal cancelToken As CancellationToken) As Task(Of List(Of String))
    Dim result As New List(Of String)
    Try
    	Await CreateContainer(cancelToken)
    
    	For Each item As IListBlobItem In container.ListBlobs(vbNull, False)
    		If TypeOf item Is CloudBlockBlob Then
    			Dim blockBlob As CloudBlockBlob = item
    			result.Add(blockBlob.Name)
    		End If
    
    	Next
    Catch ex As OperationCanceledException
    	Throw New OperationCanceledException("ListFilesAsync canceled")
    End Try
    Return result
    End Function
    

    The download & listing are asynchronously so that we can cancel at anytime and the UI will not blocking.

  6. Code inside a Form
    Private cts As CancellationTokenSource
    Private cancelToken As CancellationToken
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    	ToolStripStatusLabel1.Text = ""
    	PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
    	cts = New CancellationTokenSource()
    	cancelToken = cts.Token
    	cancelToken.ThrowIfCancellationRequested()
    
    	ListImagesAsync().ConfigureAwait(False)
    End Sub
    

    Private Async Function ListImagesAsync() As Task
    Try
    	ToolStripStatusLabel1.Text = "Retrieve Image collection"
    	Await Task.Delay(txtDelay.Text)
    
    	Dim AZBlob As New AzureBlob(ConfigurationManager.AppSettings("StorageConnectionString"), "mycontainer")
    	Dim result As List(Of String) = Await AZBlob.ListFilesAsync(cancelToken)
    	For Each imgName As String In result
    		ListBox1.Items.Add(imgName)
    
    	Next
    	ToolStripStatusLabel1.Text = ""
    Catch exCancel As OperationCanceledException
    	Dim message As String = "ListImages canceled at DemoUploadAsync"
    	MessageBox.Show(message)
    	ToolStripStatusLabel1.Text = message
    Catch ex As Exception
    	MessageBox.Show(ex.Message)
    	ToolStripStatusLabel1.Text = ex.Message
    End Try
    End Function
    

    There is Await Task.Delay(txtDelay.Text) to delay for some seconds so that we have a chance to click cancel button for demonstration purposes.

    Private Async Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    Try
    	ToolStripStatusLabel1.Text = "Uploading"
    	Await Task.Delay(txtDelay.Text)
    
    	Dim AZBlob As New AzureBlob(ConfigurationManager.AppSettings("StorageConnectionString"), "mycontainer")
    	Await AZBlob.UploadAsync(PictureBox1.ImageLocation, cancelToken)
    	MessageBox.Show("upload success")
    	ToolStripStatusLabel1.Text = ""
    	PictureBox1.Image = Nothing
    Catch exCancel As OperationCanceledException
    	Dim message As String = "upload canceled at Form"
    	MessageBox.Show(message)
    	ToolStripStatusLabel1.Text = message
    Catch ex As Exception
    	MessageBox.Show(ex.Message)
    	ToolStripStatusLabel1.Text = ex.Message
    End Try
    End Sub
    

    Private Async Sub btnRet_Click(sender As Object, e As EventArgs) Handles btnRet.Click
    Try
    	ToolStripStatusLabel1.Text = "Download Image"
    	Await Task.Delay(txtDelay.Text)
    	Dim imgName As String = ListBox1.SelectedItem.ToString()
    	Dim AZBlob As New AzureBlob(ConfigurationManager.AppSettings("StorageConnectionString"), "mycontainer")
    	Await AZBlob.DownloadAsync(imgName, cancelToken)
    	Dim fs As System.IO.FileStream = System.IO.File.OpenRead(My.Application.Info.DirectoryPath & "\" & imgName)
    
    	PictureBox1.Image = Image.FromStream(fs)
    
    	ToolStripStatusLabel1.Text = ""
    Catch exCancel As OperationCanceledException
    	Dim message As String = "download canceled at Form"
    	MessageBox.Show(message)
    	ToolStripStatusLabel1.Text = message
    Catch ex As Exception
    	MessageBox.Show(ex.Message)
    	ToolStripStatusLabel1.Text = ex.Message
    
    End Try
    End Sub
    

    Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
    	cts.Cancel()
    End Sub
    
  7. You may download full source code at below url:
    WinCloudAsyncAwait SourceCode
    to test on your own. Update the app.config file to your Azure storage account

Regards,
Agung Gugiaji

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s