public async Task <string> CopyBlobAsync(CloudBlockBlob sourceBlob, CloudBlockBlob targetBlob, CancellationToken token)
        {
            bool     tryCopy    = true;
            string   copyId     = string.Empty;
            int      retryCount = 3;
            TimeSpan timeOut    = TimeSpan.FromMinutes(3);

            while (tryCopy)
            {
                if (!string.IsNullOrEmpty(copyId))
                {
                    await targetBlob.AbortCopyAsync(copyId, token);
                }

                DateTime startTime = DateTime.Now;
                copyId = await targetBlob.StartCopyAsync(sourceBlob, token);

                while ((DateTime.Now - startTime) < timeOut)
                {
                    Thread.Sleep(100);
                    await targetBlob.FetchAttributesAsync(token);

                    switch (targetBlob.CopyState.Status)
                    {
                    case CopyStatus.Invalid:
                    case CopyStatus.Pending:
                        continue;

                    case CopyStatus.Success:
                        return(targetBlob.Uri.AbsoluteUri);

                    case CopyStatus.Aborted:
                    case CopyStatus.Failed:
                    default:
                        retryCount--;
                        if (retryCount == 0)
                        {
                            tryCopy = false;
                        }

                        break;
                    }
                }
            }

            throw new Exception("Copy blob failed");
        }