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
- Create a VB .Net WinForm project
- Add reference to WindowsAzure.Storage. You might need to install the library using Nuget Package Manager
- Create a Form like above Form’s Design picture
- 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
- 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.
- 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
- 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
What’s the maximum size file this will work with? And is there a way to include a progress indicator for large files?
Thanks a lot for your tutorial….I just have a cuestions; en which variable i must to use azure blob account y azure blob key1 or key2
Hi, key1 & key2 are both used in connection string. They are to ensure if you want to change one of key or both keys any time so that the application should not have to be stopped in order to do that changing keys