private IEnumerator <Int32> UploadFileInBlocks(AsyncEnumerator ae, String pathname, CloudBlockBlob blob, Action <Int32> blockUploaded) { Int64 fileLength; using (var fs = new FileStream(pathname, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var mmf = MemoryMappedFile.CreateFromFile(fs, null, fileLength = fs.Length, MemoryMappedFileAccess.Read, null, HandleInheritability.None, false)) { Byte[] uploadedBlocks = new Byte[(fileLength - 1) / m_blockSize + 1]; // Find out which blocks have been uploaded already? blob.BeginDownloadBlockList(BlockListingFilter.Uncommitted, AccessCondition.GenerateEmptyCondition(), null, null, ae.End(), null); yield return(1); try { foreach (ListBlockItem lbi in blob.EndDownloadBlockList(ae.DequeueAsyncResult())) { Int32 blockId = lbi.Name.FromBase64ToInt32(); uploadedBlocks[blockId] = 1; blockUploaded(blockId); } } catch (StorageException e) { if ((HttpStatusCode)e.RequestInformation.HttpStatusCode != HttpStatusCode.NotFound) { throw; } } // Start uploading the remaining blocks: Int32 blocksUploading = 0; foreach (var blockNumber in GetBlockNumbersFromArray(uploadedBlocks)) { // Start uploading up to 'm_concurrency' blocks blocksUploading++; var aeBlock = new AsyncEnumerator("Block #" + blockNumber); aeBlock.BeginExecute(UploadBlock(aeBlock, mmf, blob, blockNumber, (blockNumber == uploadedBlocks.Length - 1) ? fileLength % m_blockSize : m_blockSize), ae.End(), blockNumber); if (blocksUploading < m_concurrency) { continue; } // As each block completes uploading, start uploading a new block (if any are left) yield return(1); blocksUploading--; IAsyncResult result = ae.DequeueAsyncResult(); AsyncEnumerator.FromAsyncResult(result).EndExecute(result); blockUploaded((Int32)result.AsyncState); } // Wait until all blocks have finished uploading and then commit them all for (; blocksUploading > 0; blocksUploading--) { yield return(1); IAsyncResult result = ae.DequeueAsyncResult(); AsyncEnumerator.FromAsyncResult(result).EndExecute(result); blockUploaded((Int32)result.AsyncState); } // Commit all the blocks in order: blob.BeginPutBlockList(Enumerable.Range(0, uploadedBlocks.Length).Select(b => b.ToBase64()), ae.End(), null); yield return(1); blob.EndPutBlockList(ae.DequeueAsyncResult()); } }
public static Int64 EndCopyStream(/* this */ Stream source, IAsyncResult result) { Contract.Requires(result != null); return(AsyncEnumerator <Int64> .FromAsyncResult(result).EndExecute(result)); }
public void EndUpload(IAsyncResult asyncResult) { AsyncEnumerator.FromAsyncResult(asyncResult).EndExecute(asyncResult); }