コード例 #1
0
        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());
                }
        }
コード例 #2
0
 public static Int64 EndCopyStream(/* this */ Stream source, IAsyncResult result)
 {
     Contract.Requires(result != null);
     return(AsyncEnumerator <Int64> .FromAsyncResult(result).EndExecute(result));
 }
コード例 #3
0
 public void EndUpload(IAsyncResult asyncResult)
 {
     AsyncEnumerator.FromAsyncResult(asyncResult).EndExecute(asyncResult);
 }