public void UploadBlobAsync(CloudBlockBlob blob, string localFile, object state) { TransferType = TransferTypeEnum.Upload; //attempt to open the file first so that we throw an exception before getting into the async work using (FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read)) { } m_Blob = blob; m_FileName = localFile; BlobTransferWorkerDelegate worker = new BlobTransferWorkerDelegate(UploadBlobWorker); AsyncCallback completedCallback = new AsyncCallback(TaskCompletedCallback); lock (_sync) { if (TaskIsRunning) { throw new InvalidOperationException("The control is currently busy."); } AsyncOperation async = AsyncOperationManager.CreateOperation(state); MyAsyncContext context = new MyAsyncContext(); bool cancelled; worker.BeginInvoke(context, out cancelled, async, completedCallback, async); TaskIsRunning = true; TaskContext = context; } }
//private void DownloadBlobWorker(MyAsyncContext asyncContext, out bool cancelled, AsyncOperation async) //{ // cancelled = false; // ParallelDownloadFile(asyncContext, async); // // check for Cancelling // if (asyncContext.IsCancelling) // { // cancelled = true; // } //} private void TaskCompletedCallback(IAsyncResult ar) { // get the original worker delegate and the AsyncOperation instance BlobTransferWorkerDelegate worker = (BlobTransferWorkerDelegate)((AsyncResult)ar).AsyncDelegate; AsyncOperation async = (AsyncOperation)ar.AsyncState; bool cancelled; // finish the asynchronous operation worker.EndInvoke(out cancelled, ar); // clear the running task flag lock (_sync) { TaskIsRunning = false; TaskContext = null; } // raise the completed event var asyncOperation = ar.AsyncState as AsyncOperation; object userState = null; if (asyncOperation != null) { userState = asyncOperation.UserSuppliedState; } AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, cancelled, userState); async.PostOperationCompleted(delegate(object e) { OnTaskCompleted((AsyncCompletedEventArgs)e); }, completedArgs); }
private void UploadBlobWorker(MyAsyncContext asyncContext, out bool cancelled, AsyncOperation async) { cancelled = false; ParallelUploadFile(asyncContext, async); // check for Cancelling if (asyncContext.IsCancelling) { cancelled = true; } }
private void ParallelUploadFile(MyAsyncContext asyncContext, AsyncOperation asyncOp) { BlobTransferProgressChangedEventArgs eArgs = null; object AsyncUpdateLock = new object(); // stats from azurescope show 10 to be an optimal number of transfer threads int numThreads = 10; var file = new FileInfo(m_FileName); long fileSize = file.Length; int maxBlockSize = GetBlockSize(fileSize); long bytesUploaded = 0; int blockLength = 0; // Prepare a queue of blocks to be uploaded. Each queue item is a key-value pair where // the 'key' is block id and 'value' is the block length. Queue <KeyValuePair <int, int> > queue = new Queue <KeyValuePair <int, int> >(); List <string> blockList = new List <string>(); int blockId = 0; while (fileSize > 0) { blockLength = (int)Math.Min(maxBlockSize, fileSize); string blockIdString = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("BlockId{0}", blockId.ToString("0000000")))); KeyValuePair <int, int> kvp = new KeyValuePair <int, int>(blockId++, blockLength); queue.Enqueue(kvp); blockList.Add(blockIdString); fileSize -= blockLength; } m_Blob.DeleteIfExists(); BlobRequestOptions options = new BlobRequestOptions() { //RetryPolicy = RetryPolicies.RetryExponential(RetryPolicies.DefaultClientRetryCount, RetryPolicies.DefaultMaxBackoff), //Timeout = TimeSpan.FromSeconds(90) }; // Launch threads to upload blocks. List <Thread> threads = new List <Thread>(); for (int idxThread = 0; idxThread < numThreads; idxThread++) { Thread t = new Thread(new ThreadStart(() => { KeyValuePair <int, int> blockIdAndLength; using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read)) { while (true) { // Dequeue block details. lock (queue) { if (asyncContext.IsCancelling) { break; } if (queue.Count == 0) { break; } blockIdAndLength = queue.Dequeue(); } byte[] buff = new byte[blockIdAndLength.Value]; BinaryReader br = new BinaryReader(fs); // move the file system reader to the proper position fs.Seek(blockIdAndLength.Key * (long)maxBlockSize, SeekOrigin.Begin); br.Read(buff, 0, blockIdAndLength.Value); // Upload block. string blockName = Convert.ToBase64String(BitConverter.GetBytes( blockIdAndLength.Key)); using (MemoryStream ms = new MemoryStream(buff, 0, blockIdAndLength.Value)) { string blockIdString = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("BlockId{0}", blockIdAndLength.Key.ToString("0000000")))); string blockHash = GetMD5HashFromStream(buff); m_Blob.PutBlock(blockIdString, ms, blockHash, options: options); } lock (AsyncUpdateLock) { bytesUploaded += blockIdAndLength.Value; int progress = (int)((double)bytesUploaded / file.Length * 100); // raise the progress changed event eArgs = new BlobTransferProgressChangedEventArgs(bytesUploaded, file.Length, progress, CalculateSpeed(bytesUploaded), null); asyncOp.Post(delegate(object e) { OnTaskProgressChanged((BlobTransferProgressChangedEventArgs)e); }, eArgs); } } } })); t.Start(); threads.Add(t); } // Wait for all threads to complete uploading data. foreach (Thread t in threads) { t.Join(); } if (!asyncContext.IsCancelling) { // Commit the blocklist. m_Blob.PutBlockList(blockList, options: options); } }
private void UploadBlobWorker(MyAsyncContext asyncContext, out bool cancelled, AsyncOperation async) { cancelled = false; ParallelUploadFile(asyncContext, async); // check for Cancelling if (asyncContext.IsCancelling) { cancelled = true; } }
//private void DownloadBlobWorker(MyAsyncContext asyncContext, out bool cancelled, AsyncOperation async) //{ // cancelled = false; // ParallelDownloadFile(asyncContext, async); // // check for Cancelling // if (asyncContext.IsCancelling) // { // cancelled = true; // } //} private void TaskCompletedCallback(IAsyncResult ar) { // get the original worker delegate and the AsyncOperation instance BlobTransferWorkerDelegate worker = (BlobTransferWorkerDelegate)((AsyncResult)ar).AsyncDelegate; AsyncOperation async = (AsyncOperation)ar.AsyncState; bool cancelled; // finish the asynchronous operation worker.EndInvoke(out cancelled, ar); // clear the running task flag lock (_sync) { TaskIsRunning = false; TaskContext = null; } // raise the completed event var asyncOperation = ar.AsyncState as AsyncOperation; object userState = null; if (asyncOperation != null) { userState = asyncOperation.UserSuppliedState; } AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, cancelled, userState); async.PostOperationCompleted(delegate(object e) { OnTaskCompleted((AsyncCompletedEventArgs)e); }, completedArgs); }
private void ParallelUploadFile(MyAsyncContext asyncContext, AsyncOperation asyncOp) { BlobTransferProgressChangedEventArgs eArgs = null; object AsyncUpdateLock = new object(); // stats from azurescope show 10 to be an optimal number of transfer threads int numThreads = 10; var file = new FileInfo(m_FileName); long fileSize = file.Length; int maxBlockSize = GetBlockSize(fileSize); long bytesUploaded = 0; int blockLength = 0; // Prepare a queue of blocks to be uploaded. Each queue item is a key-value pair where // the 'key' is block id and 'value' is the block length. Queue<KeyValuePair<int, int>> queue = new Queue<KeyValuePair<int, int>>(); List<string> blockList = new List<string>(); int blockId = 0; while (fileSize > 0) { blockLength = (int)Math.Min(maxBlockSize, fileSize); string blockIdString = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("BlockId{0}", blockId.ToString("0000000")))); KeyValuePair<int, int> kvp = new KeyValuePair<int, int>(blockId++, blockLength); queue.Enqueue(kvp); blockList.Add(blockIdString); fileSize -= blockLength; } m_Blob.DeleteIfExists(); BlobRequestOptions options = new BlobRequestOptions() { //RetryPolicy = RetryPolicies.RetryExponential(RetryPolicies.DefaultClientRetryCount, RetryPolicies.DefaultMaxBackoff), //Timeout = TimeSpan.FromSeconds(90) }; // Launch threads to upload blocks. List<Thread> threads = new List<Thread>(); for (int idxThread = 0; idxThread < numThreads; idxThread++) { Thread t = new Thread(new ThreadStart(() => { KeyValuePair<int, int> blockIdAndLength; using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read)) { while (true) { // Dequeue block details. lock (queue) { if (asyncContext.IsCancelling) break; if (queue.Count == 0) break; blockIdAndLength = queue.Dequeue(); } byte[] buff = new byte[blockIdAndLength.Value]; BinaryReader br = new BinaryReader(fs); // move the file system reader to the proper position fs.Seek(blockIdAndLength.Key * (long)maxBlockSize, SeekOrigin.Begin); br.Read(buff, 0, blockIdAndLength.Value); // Upload block. string blockName = Convert.ToBase64String(BitConverter.GetBytes( blockIdAndLength.Key)); using (MemoryStream ms = new MemoryStream(buff, 0, blockIdAndLength.Value)) { string blockIdString = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("BlockId{0}", blockIdAndLength.Key.ToString("0000000")))); string blockHash = GetMD5HashFromStream(buff); m_Blob.PutBlock(blockIdString, ms, blockHash, options: options); } lock (AsyncUpdateLock) { bytesUploaded += blockIdAndLength.Value; int progress = (int)((double)bytesUploaded / file.Length * 100); // raise the progress changed event eArgs = new BlobTransferProgressChangedEventArgs(bytesUploaded, file.Length, progress, CalculateSpeed(bytesUploaded), null); asyncOp.Post(delegate(object e) { OnTaskProgressChanged((BlobTransferProgressChangedEventArgs)e); }, eArgs); } } } })); t.Start(); threads.Add(t); } // Wait for all threads to complete uploading data. foreach (Thread t in threads) { t.Join(); } if (!asyncContext.IsCancelling) { // Commit the blocklist. m_Blob.PutBlockList(blockList, options: options); } }
public void UploadBlobAsync(CloudBlockBlob blob, string localFile, object state) { TransferType = TransferTypeEnum.Upload; //attempt to open the file first so that we throw an exception before getting into the async work using (FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read)) { } m_Blob = blob; m_FileName = localFile; BlobTransferWorkerDelegate worker = new BlobTransferWorkerDelegate(UploadBlobWorker); AsyncCallback completedCallback = new AsyncCallback(TaskCompletedCallback); lock (_sync) { if (TaskIsRunning) throw new InvalidOperationException("The control is currently busy."); AsyncOperation async = AsyncOperationManager.CreateOperation(state); MyAsyncContext context = new MyAsyncContext(); bool cancelled; worker.BeginInvoke(context, out cancelled, async, completedCallback, async); TaskIsRunning = true; TaskContext = context; } }