/// <summary> /// Upload a single block. This can happen on parallel threads. /// </summary> /// <param name="blockIdSequenceNumber">The block sequence prefix value.</param> /// <param name="setResult">The set result.</param> /// <returns>A <see cref="TaskSequence"/> that dispenses a block stream.</returns> private TaskSequence DispenseBlockStream(long blockIdSequenceNumber, Action <SmallBlockMemoryStream, string, string> setResult) { int currentCallIndex = this.dispenserCallCount++; TraceHelper.WriteLine("Staring dispensBlockStream for id {0}", currentCallIndex); SmallBlockMemoryStream memoryStream = new SmallBlockMemoryStream(Constants.DefaultBufferSize); var md5Check = MD5.Create(); int totalCopied = 0, numRead = 0; do { byte[] buffer = new byte[Constants.DefaultBufferSize]; var numToRead = (int)Math.Min(buffer.Length, this.blockSize - totalCopied); var readTask = this.sourceStream.ReadAsync(buffer, 0, numToRead); yield return(readTask); numRead = readTask.Result; if (numRead != 0) { // Verify the content StreamUtilities.ComputeHash(buffer, 0, numRead, md5Check); StreamUtilities.ComputeHash(buffer, 0, numRead, this.blobHash); var writeTask = memoryStream.WriteAsync(buffer, 0, numRead); yield return(writeTask); // Materialize any exceptions var scratch = writeTask.Result; Console.WriteLine(scratch); totalCopied += numRead; } }while (numRead != 0 && totalCopied < this.blockSize); // No locking necessary as only once active Dispense Task this.dispensizedStreamSize += totalCopied; if (totalCopied != 0) { string hashVal = StreamUtilities.GetHashValue(md5Check); string blockId = Utilities.GenerateBlockIDWithHash(hashVal, blockIdSequenceNumber); this.blockList.Add(blockId); memoryStream.Position = 0; setResult(memoryStream, blockId, hashVal); } else { memoryStream.Close(); setResult(null, null, null); } TraceHelper.WriteLine("Ending dispensBlockStream for id {0}", currentCallIndex); }
/// <summary> /// Upload a single block. This can happen on parallel threads. /// </summary> /// <param name="blockIdSequenceNumber">The block sequence prefix value.</param> /// <param name="setResult">The set result.</param> /// <returns>A <see cref="TaskSequence"/> that dispenses a block stream.</returns> private TaskSequence DispenseBlockStream(long blockIdSequenceNumber, Action<SmallBlockMemoryStream, string, string> setResult) { int currentCallIndex = this.dispenserCallCount++; TraceHelper.WriteLine("Staring dispensBlockStream for id {0}", currentCallIndex); SmallBlockMemoryStream memoryStream = new SmallBlockMemoryStream(Constants.DefaultBufferSize); var md5Check = MD5.Create(); int totalCopied = 0, numRead = 0; do { byte[] buffer = new byte[Constants.DefaultBufferSize]; var numToRead = (int)Math.Min(buffer.Length, this.blockSize - totalCopied); var readTask = this.sourceStream.ReadAsync(buffer, 0, numToRead); yield return readTask; numRead = readTask.Result; if (numRead != 0) { // Verify the content StreamUtilities.ComputeHash(buffer, 0, numRead, md5Check); StreamUtilities.ComputeHash(buffer, 0, numRead, this.blobHash); var writeTask = memoryStream.WriteAsync(buffer, 0, numRead); yield return writeTask; // Materialize any exceptions var scratch = writeTask.Result; totalCopied += numRead; } } while (numRead != 0 && totalCopied < this.blockSize); // No locking necessary as only once active Dispense Task this.dispensizedStreamSize += totalCopied; if (totalCopied != 0) { string hashVal = StreamUtilities.GetHashValue(md5Check); string blockId = Utilities.GenerateBlockIDWithHash(hashVal, blockIdSequenceNumber); this.blockList.Add(blockId); memoryStream.Position = 0; setResult(memoryStream, blockId, hashVal); } else { memoryStream.Close(); setResult(null, null, null); } TraceHelper.WriteLine("Ending dispensBlockStream for id {0}", currentCallIndex); }