public ICancellableAsyncResult BeginOpenRead(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { StorageAsyncResult<Stream> storageAsyncResult = new StorageAsyncResult<Stream>(callback, state); ICancellableAsyncResult result = this.BeginFetchAttributes( accessCondition, options, operationContext, ar => { try { this.EndFetchAttributes(ar); storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); storageAsyncResult.Result = new BlobReadStream(this, streamAccessCondition, modifiedOptions, operationContext); storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("buffer", buffer); CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); StorageAsyncResult<int> result = new StorageAsyncResult<int>(callback, state); try { result.Result = this.Read(buffer, offset, count); result.OnComplete(); } catch (Exception e) { result.OnComplete(e); } return result; }
/// <summary> /// Begins an asynchronous write operation. /// </summary> /// <param name="buffer">The buffer to write data from.</param> /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param> /// <param name="count">The number of bytes to write.</param> /// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param> /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param> /// <returns>An IAsyncResult that represents the asynchronous write, which could still be pending.</returns> public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("buffer", buffer); CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); StorageAsyncResult <NullType> result = new StorageAsyncResult <NullType>(callback, state); try { this.Write(buffer, offset, count); result.OnComplete(); } catch (Exception e) { result.OnComplete(e); } return(result); }
private void WriteStreamCallback(IAsyncResult ar) { StorageAsyncResult <NullType> storageAsyncResult = (StorageAsyncResult <NullType>)ar.AsyncState; storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); Exception endException = null; try { this.cryptoStream.EndWrite(ar); this.position += (int)storageAsyncResult.OperationState; } catch (Exception e) { endException = e; } storageAsyncResult.OnComplete(endException); }
private void WriteRange(Stream rangeData, long offset, string contentMD5, StorageAsyncResult <NullType> asyncResult) { this.noPendingWritesEvent.Increment(); this.parallelOperationSemaphore.WaitAsync(calledSynchronously => { try { ICancellableAsyncResult result = this.file.BeginWriteRange( rangeData, offset, contentMD5, this.accessCondition, this.options, this.operationContext, this.WriteRangeCallback, null /* state */); if (asyncResult != null) { // We do not need to do this inside a lock, as asyncResult is // not returned to the user yet. asyncResult.CancelDelegate = result.Cancel; } } catch (Exception e) { this.lastException = e; this.noPendingWritesEvent.Decrement(); this.parallelOperationSemaphore.Release(); } finally { if (asyncResult != null) { asyncResult.UpdateCompletedSynchronously(calledSynchronously); asyncResult.OnComplete(this.lastException); } } }); }
private void DownloadRangeToStreamCallback(IAsyncResult ar) { StorageAsyncResult <int> storageAsyncResult = (StorageAsyncResult <int>)ar.AsyncState; storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.blob.EndDownloadRangeToStream(ar); ArraySegment <byte> bufferSegment = (ArraySegment <byte>)storageAsyncResult.OperationState; this.internalBuffer.Seek(0, SeekOrigin.Begin); storageAsyncResult.Result = this.ConsumeBuffer(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count); } catch (Exception e) { this.lastException = e; } storageAsyncResult.OnComplete(this.lastException); }
private void WriteBlock(Stream blockData, string blockId, string blockMD5, StorageAsyncResult <NullType> asyncResult) { this.noPendingWritesEvent.Increment(); this.parallelOperationSemaphore.WaitAsync(calledSynchronously => { try { ICancellableAsyncResult result = this.blockBlob.BeginPutBlock( blockId, blockData, blockMD5, this.accessCondition, this.options, this.operationContext, this.PutBlockCallback, null /* state */); if (asyncResult != null) { // We do not need to do this inside a lock, as asyncResult is // not returned to the user yet. asyncResult.CancelDelegate = result.Cancel; } } catch (Exception e) { this.lastException = e; } finally { if (asyncResult != null) { asyncResult.UpdateCompletedSynchronously(calledSynchronously); asyncResult.OnComplete(this.lastException); } } }); }
private void DispatchReadAsync(StorageAsyncResult <int> storageAsyncResult, byte[] buffer, int offset, int count) { storageAsyncResult.OperationState = new ArraySegment <byte>(buffer, offset, count); try { this.internalBuffer.SetLength(0); this.file.BeginDownloadRangeToStream( this.internalBuffer, this.currentOffset, this.GetReadSize(), null /* accessCondition */, this.options, this.operationContext, this.DownloadRangeToStreamCallback, storageAsyncResult); } catch (Exception e) { this.lastException = e; throw; } }
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { // Keep buffering until we have 16 bytes of IV. if (this.bufferIV && this.position < 16) { int bytesToCopy = 16 - (int)this.position; bytesToCopy = count > bytesToCopy ? bytesToCopy : count; Array.Copy(buffer, offset, this.iv, (int)this.position, bytesToCopy); this.position += bytesToCopy; offset += bytesToCopy; count -= bytesToCopy; } // Wrap user stream with LengthLimitingStream. This stream will be used to discard the extra bytes we downloaded in order to deal with AES block size. // Create crypto stream around the length limiting stream once per download and start writing to it. During retries, the state is maintained and // new crypto streams will not be created each time. if (this.cryptoStream == null) { LengthLimitingStream lengthLimitingStream = new LengthLimitingStream(this.userStream, this.discardFirst, this.userProvidedLength); this.cryptoStream = this.encryptionPolicy.DecryptBlob(lengthLimitingStream, this.metadata, out this.transform, this.requireEncryption, iv: !this.bufferIV ? null : this.iv, noPadding: this.noPadding); } StorageAsyncResult <NullType> storageAsyncResult = new StorageAsyncResult <NullType>(callback, state); if (count <= 0) { storageAsyncResult.OnComplete(); } else { // Route the remaining data through the crypto stream. storageAsyncResult.OperationState = count; this.cryptoStream.BeginWrite(buffer, offset, count, this.WriteStreamCallback, storageAsyncResult); } return(storageAsyncResult); }
public ICancellableAsyncResult BeginPutBlock(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("blockData", blockData); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; operationContext = operationContext ?? new OperationContext(); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); if (blockData.CanSeek && !requiresContentMD5) { this.PutBlockHandler(blockId, blockData, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); } else { ExecutionState<NullType> tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; Stream seekableStream; Stream writeToStream; if (blockData.CanSeek) { seekableStream = blockData; writeToStream = Stream.Null; } else { seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); writeToStream = seekableStream; } long startPosition = seekableStream.Position; StreamDescriptor streamCopyState = new StreamDescriptor(); blockData.WriteToAsync( writeToStream, null /* copyLength */, Constants.MaxBlockSize, requiresContentMD5, tempExecutionState, streamCopyState, completedState => { storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { try { if (requiresContentMD5) { contentMD5 = streamCopyState.Md5; } seekableStream.Position = startPosition; this.PutBlockHandler(blockId, seekableStream, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }); } return storageAsyncResult; }
public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); StorageAsyncResult<bool> storageAsyncResult = new StorageAsyncResult<bool>(callback, state) { RequestOptions = modifiedOptions, OperationContext = operationContext, }; this.DeleteIfExistsHandler(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext, storageAsyncResult); return storageAsyncResult; }
public ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { SyncMemoryStream stream = new SyncMemoryStream(target, index); StorageAsyncResult<int> storageAsyncResult = new StorageAsyncResult<int>(callback, state) { OperationState = stream }; ICancellableAsyncResult result = this.BeginDownloadRangeToStream( stream, blobOffset, length, accessCondition, options, operationContext, this.DownloadRangeToByteArrayCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
internal ICancellableAsyncResult BeginUploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("source", source); if (!source.CanSeek) { throw new InvalidOperationException(); } if (length.HasValue) { CommonUtility.AssertInBounds("length", (long)length, 1, source.Length - source.Position); } else { length = source.Length - source.Position; } if ((length % Constants.PageSize) != 0) { throw new ArgumentException(SR.InvalidPageSize, "source"); } this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); ExecutionState<NullType> tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); ICancellableAsyncResult result = this.BeginOpenWrite( length, accessCondition, modifiedOptions, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; try { CloudBlobStream blobStream = this.EndOpenWrite(ar); storageAsyncResult.OperationState = blobStream; source.WriteToAsync( blobStream, length, null /* maxLength */, false, tempExecutionState, null /* streamCopyState */, completedState => { storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { try { lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; ICancellableAsyncResult commitResult = blobStream.BeginCommit( CloudBlob.BlobOutputStreamCommitCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = commitResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }, null /* state */); // We do not need to do this inside a lock, as storageAsyncResult is // not returned to the user yet. storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
internal ICancellableAsyncResult BeginUploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("source", source); if (length.HasValue) { CommonUtility.AssertInBounds("length", length.Value, 1); if (source.CanSeek && length > source.Length - source.Position) { throw new ArgumentOutOfRangeException("length", SR.StreamLengthShortError); } } this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); ExecutionState<NullType> tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); bool lessThanSingleBlobThreshold = CloudBlockBlob.IsLessThanSingleBlobThreshold(source, length, modifiedOptions, false); modifiedOptions.AssertPolicyIfRequired(); if (modifiedOptions.ParallelOperationThreadCount.Value == 1 && lessThanSingleBlobThreshold) { // Because we may or may not want to calculate the MD5, and we may or may not want to encrypt, rather than have four branching code // paths, here we have an action that we will run, which continually gets added to, depending on which operations we need to do. // The confusing part is that we have to build it from the bottom up. string md5 = null; Stream sourceStream = source; Action actionToRun = null; Action uploadAction = () => { if (md5 == null && modifiedOptions.UseTransactionalMD5.Value) { throw new ArgumentException(SR.PutBlobNeedsStoreBlobContentMD5, "options"); } this.UploadFromStreamHandler( sourceStream, length, md5, accessCondition, operationContext, modifiedOptions, storageAsyncResult); }; actionToRun = uploadAction; if (modifiedOptions.StoreBlobContentMD5.Value) { Action<Action> calculateMD5 = (continuation) => { long startPosition = sourceStream.Position; StreamDescriptor streamCopyState = new StreamDescriptor(); sourceStream.WriteToAsync( Stream.Null, length, null /* maxLength */, true, tempExecutionState, streamCopyState, completedState => { ContinueAsyncOperation(storageAsyncResult, completedState, () => { if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { sourceStream.Position = startPosition; md5 = streamCopyState.Md5; continuation(); } }); }); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } }; Action oldActionToRun = actionToRun; actionToRun = () => calculateMD5(oldActionToRun); } if (modifiedOptions.EncryptionPolicy != null) { Action<Action> encryptStream = continuation => { SyncMemoryStream syncMemoryStream = new SyncMemoryStream(); options.AssertPolicyIfRequired(); sourceStream = syncMemoryStream; if (modifiedOptions.EncryptionPolicy.EncryptionMode != BlobEncryptionMode.FullBlob) { throw new InvalidOperationException(SR.InvalidEncryptionMode, null); } ICryptoTransform transform = options.EncryptionPolicy.CreateAndSetEncryptionContext(this.Metadata, false /* noPadding */); CryptoStream cryptoStream = new CryptoStream(syncMemoryStream, transform, CryptoStreamMode.Write); StreamDescriptor streamCopyState = new StreamDescriptor(); source.WriteToAsync(cryptoStream, length, null, false, tempExecutionState, streamCopyState, completedState => { ContinueAsyncOperation(storageAsyncResult, completedState, () => { if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { // Flush the CryptoStream in order to make sure that the last block of data is flushed. This call is a sync call // but it is ok to have it because we're just writing to a memory stream. cryptoStream.FlushFinalBlock(); // After the tempStream has been written to, we need to seek back to the beginning, so that it can be read from. sourceStream.Seek(0, SeekOrigin.Begin); length = syncMemoryStream.Length; continuation(); } }); }); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } }; Action oldActionToRun = actionToRun; actionToRun = () => encryptStream(oldActionToRun); } actionToRun(); } else { ICancellableAsyncResult result = this.BeginOpenWrite( accessCondition, modifiedOptions, operationContext, ar => { ContinueAsyncOperation(storageAsyncResult, ar, () => { CloudBlobStream blobStream = this.EndOpenWrite(ar); storageAsyncResult.OperationState = blobStream; source.WriteToAsync( blobStream, length, null /* maxLength */, false, tempExecutionState, null /* streamCopyState */, completedState => { ContinueAsyncOperation(storageAsyncResult, completedState, () => { if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { ICancellableAsyncResult commitResult = blobStream.BeginCommit( CloudBlob.BlobOutputStreamCommitCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = commitResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } }); }); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } }); }, null /* state */); // We do not need to do this inside a lock, as storageAsyncResult is // not returned to the user yet. storageAsyncResult.CancelDelegate = result.Cancel; } return storageAsyncResult; }
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { StorageAsyncResult<NullType> result = new StorageAsyncResult<NullType>(callback, state); if (this.completeSynchronously) { result.UpdateCompletedSynchronously(this.completeSynchronously); try { this.Write(buffer, offset, count); result.OnComplete(); } catch (Exception e) { result.OnComplete(e); } } else { ThreadPool.QueueUserWorkItem(_ => { result.UpdateCompletedSynchronously(this.completeSynchronously); try { this.Write(buffer, offset, count); result.OnComplete(); } catch (Exception e) { result.OnComplete(e); } }, null); } return result; }
/// <summary> /// Begins an asynchronous write operation. /// </summary> /// <param name="buffer">An array of bytes. This method copies count bytes from /// buffer to the current stream. </param> /// <param name="offset">The zero-based byte offset in buffer at which to begin /// copying bytes to the current stream.</param> /// <param name="count">The number of bytes to be written to the current stream.</param> /// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param> /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param> /// <returns>An <c>IAsyncResult</c> that represents the asynchronous write, which could still be pending.</returns> public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("buffer", buffer); CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); if (this.committed) { throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); } StorageAsyncResult <NullType> storageAsyncResult = new StorageAsyncResult <NullType>(callback, state); StorageAsyncResult <NullType> currentAsyncResult = storageAsyncResult; this.currentOffset += count; int initialOffset = offset; int initialCount = count; bool dispatched = false; if (this.lastException == null) { while (count > 0) { int maxBytesToWrite = this.streamWriteSizeInBytes - (int)this.internalBuffer.Length; int bytesToWrite = Math.Min(count, maxBytesToWrite); this.internalBuffer.Write(buffer, offset, bytesToWrite); if (this.blockMD5 != null) { this.blockMD5.UpdateHash(buffer, offset, bytesToWrite); } count -= bytesToWrite; offset += bytesToWrite; if (bytesToWrite == maxBytesToWrite) { this.DispatchWrite(currentAsyncResult); dispatched = true; // Do not use the IAsyncResult we are going to return more // than once, as otherwise its callback will be called more // than once. currentAsyncResult = null; } } } // Update transactional, then update full blob, in that order. // This way, if there's any bit corruption that happens in between the two, we detect it at PutBlock on the service, // rather than GetBlob + validate on the client if (this.blobMD5 != null) { this.blobMD5.UpdateHash(buffer, initialOffset, initialCount); } if (!dispatched) { storageAsyncResult.OnComplete(this.lastException); } return(storageAsyncResult); }
public override ICancellableAsyncResult BeginCommit(AsyncCallback callback, object state) { if (this.committed) { throw new InvalidOperationException(SR.FileStreamAlreadyCommitted); } StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); ICancellableAsyncResult result = this.BeginFlush(this.CommitFlushCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
/// <summary> /// Dispatches an async read operation that either reads from the cache or makes a call to /// the server. /// </summary> /// <param name="storageAsyncResult">The reference to the pending asynchronous request to finish.</param> /// <param name="buffer">The buffer to read the data into.</param> /// <param name="offset">The byte offset in buffer at which to begin writing /// data read from the stream.</param> /// <param name="count">The maximum number of bytes to read.</param> private void DispatchReadAsync(StorageAsyncResult<int> storageAsyncResult, byte[] buffer, int offset, int count) { storageAsyncResult.OperationState = new ArraySegment<byte>(buffer, offset, count); try { this.internalBuffer.SetLength(0); this.blob.BeginDownloadRangeToStream( this.internalBuffer, this.currentOffset, this.GetReadSize(), this.accessCondition, this.options, this.operationContext, this.DownloadRangeToStreamCallback, storageAsyncResult); } catch (Exception e) { this.lastException = e; throw; } }
internal ICancellableAsyncResult BeginUploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("source", source); if (length.HasValue) { CommonUtility.AssertInBounds("length", length.Value, 1); if (source.CanSeek && length > source.Length - source.Position) { throw new ArgumentOutOfRangeException("length", SR.StreamLengthShortError); } } this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); ExecutionState<NullType> tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); bool lessThanSingleBlobThreshold = source.CanSeek && (length ?? source.Length - source.Position) <= this.ServiceClient.SingleBlobUploadThresholdInBytes; if (this.ServiceClient.ParallelOperationThreadCount == 1 && lessThanSingleBlobThreshold) { if (modifiedOptions.StoreBlobContentMD5.Value) { long startPosition = source.Position; StreamDescriptor streamCopyState = new StreamDescriptor(); source.WriteToAsync( Stream.Null, length, null /* maxLength */, true, tempExecutionState, streamCopyState, completedState => { storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); try { lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { source.Position = startPosition; this.UploadFromStreamHandler( source, length, streamCopyState.Md5, accessCondition, operationContext, modifiedOptions, storageAsyncResult); } } } catch (Exception e) { storageAsyncResult.OnComplete(e); } }); // We do not need to do this inside a lock, as storageAsyncResult is // not returned to the user yet. storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; } else { if (modifiedOptions.UseTransactionalMD5.Value) { throw new ArgumentException(SR.PutBlobNeedsStoreBlobContentMD5, "options"); } this.UploadFromStreamHandler( source, length, null /* contentMD5 */, accessCondition, operationContext, modifiedOptions, storageAsyncResult); } } else { ICancellableAsyncResult result = this.BeginOpenWrite( accessCondition, modifiedOptions, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; try { CloudBlobStream blobStream = this.EndOpenWrite(ar); storageAsyncResult.OperationState = blobStream; source.WriteToAsync( blobStream, length, null /* maxLength */, false, tempExecutionState, null /* streamCopyState */, completedState => { storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); if (completedState.ExceptionRef != null) { storageAsyncResult.OnComplete(completedState.ExceptionRef); } else { try { lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; ICancellableAsyncResult commitResult = blobStream.BeginCommit( CloudBlobSharedImpl.BlobOutputStreamCommitCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = commitResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }); storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }, null /* state */); // We do not need to do this inside a lock, as storageAsyncResult is // not returned to the user yet. storageAsyncResult.CancelDelegate = result.Cancel; } return storageAsyncResult; }
/// <summary> /// Begins an asynchronous read operation. /// </summary> /// <param name="buffer">The buffer to read the data into.</param> /// <param name="offset">The byte offset in buffer at which to begin writing /// data read from the stream.</param> /// <param name="count">The maximum number of bytes to read.</param> /// <param name="callback">An optional asynchronous callback, to be called when the read is complete.</param> /// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param> /// <returns>An <c>IAsyncResult</c> that represents the asynchronous read, which could still be pending.</returns> public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("buffer", buffer); CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); if (this.readPending) { throw new InvalidOperationException(SR.BlobStreamReadPending); } try { this.readPending = true; StorageAsyncResult<int> storageAsyncResult = new StorageAsyncResult<int>(callback, state); if (this.lastException != null) { storageAsyncResult.OnComplete(this.lastException); return storageAsyncResult; } if ((this.currentOffset == this.Length) || (count == 0)) { storageAsyncResult.Result = 0; storageAsyncResult.OnComplete(); return storageAsyncResult; } int readCount = this.ConsumeBuffer(buffer, offset, count); if (readCount > 0) { storageAsyncResult.Result = readCount; storageAsyncResult.OnComplete(); return storageAsyncResult; } this.DispatchReadAsync(storageAsyncResult, buffer, offset, count); return storageAsyncResult; } catch (Exception) { this.readPending = false; throw; } }
private void WriteRange(Stream rangeData, long offset, string contentMD5, StorageAsyncResult<NullType> asyncResult) { this.noPendingWritesEvent.Increment(); this.parallelOperationSemaphore.WaitAsync(calledSynchronously => { try { ICancellableAsyncResult result = this.file.BeginWriteRange( rangeData, offset, contentMD5, this.accessCondition, this.options, this.operationContext, this.WriteRangeCallback, null /* state */); if (asyncResult != null) { // We do not need to do this inside a lock, as asyncResult is // not returned to the user yet. asyncResult.CancelDelegate = result.Cancel; } } catch (Exception e) { this.lastException = e; } finally { if (asyncResult != null) { asyncResult.UpdateCompletedSynchronously(calledSynchronously); asyncResult.OnComplete(this.lastException); } } }); }
public override ICancellableAsyncResult BeginFlush(AsyncCallback callback, object state) { if (this.committed) { throw new InvalidOperationException(SR.FileStreamAlreadyCommitted); } if (this.flushPending) { // We cannot allow more than one BeginFlush at a time, because // RegisterWaitForSingleObject would need duplicated handles // of noPendingWritesEvent for each call. throw new InvalidOperationException(SR.FileStreamFlushPending); } try { this.flushPending = true; this.DispatchWrite(null /* asyncResult */); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); if ((this.lastException != null) || this.noPendingWritesEvent.Wait(0)) { storageAsyncResult.OnComplete(this.lastException); } else { RegisteredWaitHandle waitHandle = ThreadPool.RegisterWaitForSingleObject( this.noPendingWritesEvent.WaitHandle, this.WaitForPendingWritesCallback, storageAsyncResult, -1, true); storageAsyncResult.OperationState = waitHandle; storageAsyncResult.CancelDelegate = () => { waitHandle.Unregister(null /* waitObject */); storageAsyncResult.OnComplete(this.lastException); }; } return storageAsyncResult; } catch (Exception) { this.flushPending = false; throw; } }
/// <summary> /// Waits for the pending asynchronous commit to complete. /// </summary> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> public override void EndCommit(IAsyncResult asyncResult) { StorageAsyncResult <NullType> storageAsyncResult = (StorageAsyncResult <NullType>)asyncResult; storageAsyncResult.End(); }
/// <summary> /// Dispatches a write operation. /// </summary> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> private void DispatchWrite(StorageAsyncResult<NullType> asyncResult) { if (this.internalBuffer.Length == 0) { if (asyncResult != null) { asyncResult.OnComplete(this.lastException); } return; } MultiBufferMemoryStream bufferToUpload = this.internalBuffer; this.internalBuffer = new MultiBufferMemoryStream(this.file.ServiceClient.BufferManager); bufferToUpload.Seek(0, SeekOrigin.Begin); string bufferMD5 = null; if (this.rangeMD5 != null) { bufferMD5 = this.rangeMD5.ComputeHash(); this.rangeMD5.Dispose(); this.rangeMD5 = new MD5Wrapper(); } long offset = this.currentFileOffset; this.currentFileOffset += bufferToUpload.Length; this.WriteRange(bufferToUpload, offset, bufferMD5, asyncResult); }
private void CommitFlushCallback(IAsyncResult ar) { StorageAsyncResult <NullType> storageAsyncResult = (StorageAsyncResult <NullType>)ar.AsyncState; storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); this.committed = true; lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; try { this.EndFlush(ar); if (this.blockBlob != null) { if (this.blobMD5 != null) { this.blockBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); } ICancellableAsyncResult result = this.blockBlob.BeginPutBlockList( this.blockList, this.accessCondition, this.options, this.operationContext, this.PutBlockListCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; } else { if (this.blobMD5 != null) { this.Blob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); ICancellableAsyncResult result = this.Blob.BeginSetProperties( this.accessCondition, this.options, this.operationContext, this.SetPropertiesCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; } else { storageAsyncResult.OnComplete(); } } if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } catch (Exception e) { this.lastException = e; storageAsyncResult.OnComplete(e); } } }
/// <summary> /// Begins an asynchronous write operation. /// </summary> /// <param name="buffer">An array of bytes. This method copies count bytes from /// buffer to the current stream. </param> /// <param name="offset">The zero-based byte offset in buffer at which to begin /// copying bytes to the current stream.</param> /// <param name="count">The number of bytes to be written to the current stream.</param> /// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param> /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param> /// <returns>An <c>IAsyncResult</c> that represents the asynchronous write, which could still be pending.</returns> public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("buffer", buffer); CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); if (this.committed) { throw new InvalidOperationException(SR.FileStreamAlreadyCommitted); } if (this.fileMD5 != null) { this.fileMD5.UpdateHash(buffer, offset, count); } StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); StorageAsyncResult<NullType> currentChainedResult = storageAsyncResult; this.currentOffset += count; bool dispatched = false; if (this.lastException == null) { while (count > 0) { int maxBytesToWrite = this.streamWriteSizeInBytes - (int)this.internalBuffer.Length; int bytesToWrite = Math.Min(count, maxBytesToWrite); this.internalBuffer.Write(buffer, offset, bytesToWrite); if (this.rangeMD5 != null) { this.rangeMD5.UpdateHash(buffer, offset, bytesToWrite); } count -= bytesToWrite; offset += bytesToWrite; if (bytesToWrite == maxBytesToWrite) { this.DispatchWrite(currentChainedResult); dispatched = true; // Do not use the IAsyncResult we are going to return more // than once, as otherwise its callback will be called more // than once. currentChainedResult = null; } } } if (!dispatched) { storageAsyncResult.OnComplete(this.lastException); } return storageAsyncResult; }
/// <summary> /// Starts an asynchronous AppendBlock operation as soon as the parallel /// operation semaphore becomes available. Since parallelism is always set /// to 1 for append blobs, appendblock operations are called serially. /// </summary> /// <param name="blockData">Data to be uploaded.</param> /// <param name="offset">Offset within the append blob to be used to set the append offset conditional header.</param> /// <param name="blockMD5">MD5 hash of the data to be uploaded.</param> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> private void WriteAppendBlock(Stream blockData, long offset, string blockMD5, StorageAsyncResult <NullType> asyncResult) { this.noPendingWritesEvent.Increment(); this.parallelOperationSemaphore.WaitAsync(calledSynchronously => { try { this.accessCondition.IfAppendPositionEqual = offset; int previousResultsCount = this.operationContext.RequestResults.Count; ICancellableAsyncResult result = this.appendBlob.BeginAppendBlock( blockData, blockMD5, this.accessCondition, this.options, this.operationContext, this.AppendBlockCallback, previousResultsCount /* state */); if (asyncResult != null) { // We do not need to do this inside a lock, as asyncResult is // not returned to the user yet. asyncResult.CancelDelegate = result.Cancel; } } catch (Exception e) { this.lastException = e; this.noPendingWritesEvent.Decrement(); this.parallelOperationSemaphore.Release(); } finally { if (asyncResult != null) { asyncResult.UpdateCompletedSynchronously(calledSynchronously); asyncResult.OnComplete(this.lastException); } } }); }
private static void ContinueAsyncOperation(StorageAsyncResult<NullType> storageAsyncResult, IAsyncResult result, Action actionToTakeInTheLock) { storageAsyncResult.UpdateCompletedSynchronously(result.CompletedSynchronously); try { lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; actionToTakeInTheLock(); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } }
public virtual ICancellableAsyncResult BeginOpenWrite(bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { this.attributes.AssertNoSnapshot(); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); StorageAsyncResult<CloudBlobStream> storageAsyncResult = new StorageAsyncResult<CloudBlobStream>(callback, state); ICancellableAsyncResult result; #if !(WINDOWS_RT || ASPNET_K || PORTABLE) ICryptoTransform transform = null; #endif if (createNew) { #if !(WINDOWS_RT || ASPNET_K || PORTABLE) if (options != null && options.EncryptionPolicy != null) { transform = options.EncryptionPolicy.CreateAndSetEncryptionContext(this.Metadata, false /* noPadding */); } #endif result = this.BeginCreateOrReplace( accessCondition, options, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.EndCreateOrReplace(ar); if (accessCondition != null) { accessCondition = new AccessCondition() { LeaseId = accessCondition.LeaseId, IfAppendPositionEqual = accessCondition.IfAppendPositionEqual, IfMaxSizeLessThanOrEqual = accessCondition.IfMaxSizeLessThanOrEqual }; } #if !(WINDOWS_RT || ASPNET_K || PORTABLE) if (modifiedOptions.EncryptionPolicy != null) { storageAsyncResult.Result = new BlobEncryptedWriteStream(this, accessCondition, modifiedOptions, operationContext, transform); } else #endif { storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); } storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); } else { if (modifiedOptions.StoreBlobContentMD5.Value) { throw new ArgumentException(SR.MD5NotPossible); } #if !(WINDOWS_RT || ASPNET_K || PORTABLE) if (modifiedOptions.EncryptionPolicy != null) { throw new ArgumentException(SR.EncryptionNotSupportedForExistingBlobs); } #endif // Although we don't need any properties from the service, we should make this call in order to honor the user specified conditional headers // while opening an existing stream and to get the append position for an existing blob if user didn't specify one. result = this.BeginFetchAttributes( accessCondition, options, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.EndFetchAttributes(ar); if (accessCondition != null) { accessCondition = new AccessCondition() { LeaseId = accessCondition.LeaseId, IfAppendPositionEqual = accessCondition.IfAppendPositionEqual }; } storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); } storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { this.attributes.AssertNoSnapshot(); bool createNew = size.HasValue; BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); StorageAsyncResult<CloudBlobStream> storageAsyncResult = new StorageAsyncResult<CloudBlobStream>(callback, state); ICancellableAsyncResult result; modifiedOptions.AssertPolicyIfRequired(); if (createNew) { #if !(WINDOWS_RT || ASPNET_K || PORTABLE) ICryptoTransform transform = null; if (options != null && options.EncryptionPolicy != null) { #if WINDOWS_PHONE throw new InvalidOperationException(SR.EncryptionNotSupportedForPageBlobsOnPhone); #else transform = options.EncryptionPolicy.CreateAndSetEncryptionContext(this.Metadata, true /* noPadding */); #endif } #endif result = this.BeginCreate( size.Value, accessCondition, options, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.EndCreate(ar); if (accessCondition != null) { accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); } #if !(WINDOWS_RT || ASPNET_K || PORTABLE) if (modifiedOptions.EncryptionPolicy != null) { storageAsyncResult.Result = new BlobEncryptedWriteStream(this, this.Properties.Length, createNew, accessCondition, modifiedOptions, operationContext, transform); } else #endif { storageAsyncResult.Result = new BlobWriteStream(this, this.Properties.Length, createNew, accessCondition, modifiedOptions, operationContext); } storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); } else { if (modifiedOptions.StoreBlobContentMD5.Value) { throw new ArgumentException(SR.MD5NotPossible); } #if !(WINDOWS_RT || ASPNET_K || PORTABLE) if (modifiedOptions.EncryptionPolicy != null) { throw new ArgumentException(SR.EncryptionNotSupportedForExistingBlobs); } #endif result = this.BeginFetchAttributes( accessCondition, options, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.EndFetchAttributes(ar); if (accessCondition != null) { accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); } storageAsyncResult.Result = new BlobWriteStream(this, this.Properties.Length, createNew, accessCondition, modifiedOptions, operationContext); storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); } storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
public ICancellableAsyncResult BeginCreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); StorageAsyncResult<bool> storageAsyncResult = new StorageAsyncResult<bool>(callback, state) { RequestOptions = modifiedOptions, OperationContext = operationContext, }; this.CreateIfNotExistsHandler(accessType, modifiedOptions, operationContext, storageAsyncResult); return storageAsyncResult; }
/// <summary> /// Begins an asynchronous operation to download the blob's contents as a string. /// </summary> /// <param name="encoding">An object that indicates the text encoding to use.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes.</param> /// <param name="state">A user-defined object that will be passed to the callback delegate.</param> /// <returns>An <see cref="ICancellableAsyncResult"/> that references the asynchronous operation.</returns> public ICancellableAsyncResult BeginDownloadText(Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { SyncMemoryStream stream = new SyncMemoryStream(); StorageAsyncResult<string> storageAsyncResult = new StorageAsyncResult<string>(callback, state) { OperationState = Tuple.Create(stream, encoding) }; ICancellableAsyncResult result = this.BeginDownloadToStream( stream, accessCondition, options, operationContext, this.DownloadTextCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
private void CreateIfNotExistsHandler(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult<bool> storageAsyncResult) { ICancellableAsyncResult savedExistsResult = this.BeginExists( true, options, operationContext, existsResult => { storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; try { bool exists = this.EndExists(existsResult); if (exists) { storageAsyncResult.Result = false; storageAsyncResult.OnComplete(); return; } ICancellableAsyncResult savedCreateResult = this.BeginCreate( accessType, options, operationContext, createResult => { storageAsyncResult.UpdateCompletedSynchronously(createResult.CompletedSynchronously); storageAsyncResult.CancelDelegate = null; try { this.EndCreate(createResult); storageAsyncResult.Result = true; storageAsyncResult.OnComplete(); } catch (StorageException e) { if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) { if ((e.RequestInformation.ExtendedErrorInformation == null) || (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerAlreadyExists)) { storageAsyncResult.Result = false; storageAsyncResult.OnComplete(); } else { storageAsyncResult.OnComplete(e); } } else { storageAsyncResult.OnComplete(e); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); storageAsyncResult.CancelDelegate = savedCreateResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }, null /* state */); // We do not need to do this inside a lock, as storageAsyncResult is // not returned to the user yet. storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; }
/// <summary> /// Begins an asynchronous operation to open a stream for writing to the blob. /// </summary> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param> /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes.</param> /// <param name="state">A user-defined object that will be passed to the callback delegate.</param> /// <returns>An <see cref="ICancellableAsyncResult"/> that references the asynchronous operation.</returns> public ICancellableAsyncResult BeginOpenWrite(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { this.attributes.AssertNoSnapshot(); StorageAsyncResult<CloudBlobStream> storageAsyncResult = new StorageAsyncResult<CloudBlobStream>(callback, state); BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); if ((accessCondition != null) && accessCondition.IsConditional) { ICancellableAsyncResult result = this.BeginFetchAttributes( accessCondition, options, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { this.EndFetchAttributes(ar); } catch (StorageException e) { if ((e.RequestInformation != null) && (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) && string.IsNullOrEmpty(accessCondition.IfMatchETag)) { // If we got a 404 and the condition was not an If-Match, // we should continue with the operation. } else { storageAsyncResult.OnComplete(e); return; } } catch (Exception e) { storageAsyncResult.OnComplete(e); return; } storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); storageAsyncResult.OnComplete(); }, null /* state */); storageAsyncResult.CancelDelegate = result.Cancel; } else { storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); storageAsyncResult.OnComplete(); } return storageAsyncResult; }
public override ICancellableAsyncResult BeginCommit(AsyncCallback callback, object state) { StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state); ICancellableAsyncResult result = this.BeginFlush(this.CommitFlushCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = result.Cancel; return storageAsyncResult; }
private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult<bool> storageAsyncResult) { lock (storageAsyncResult.CancellationLockerObject) { ICancellableAsyncResult savedExistsResult = this.BeginExists( options, operationContext, existsResult => { storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); lock (storageAsyncResult.CancellationLockerObject) { storageAsyncResult.CancelDelegate = null; try { bool exists = this.EndExists(existsResult); if (!exists) { storageAsyncResult.Result = false; storageAsyncResult.OnComplete(); return; } ICancellableAsyncResult savedDeleteResult = this.BeginDelete( deleteSnapshotsOption, accessCondition, options, operationContext, deleteResult => { storageAsyncResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously); storageAsyncResult.CancelDelegate = null; try { this.EndDelete(deleteResult); storageAsyncResult.Result = true; storageAsyncResult.OnComplete(); } catch (StorageException e) { if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) { if ((e.RequestInformation.ExtendedErrorInformation == null) || (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) { storageAsyncResult.Result = false; storageAsyncResult.OnComplete(); } else { storageAsyncResult.OnComplete(e); } } else { storageAsyncResult.OnComplete(e); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* state */); storageAsyncResult.CancelDelegate = savedDeleteResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } catch (Exception e) { storageAsyncResult.OnComplete(e); } } }, null /* state */); storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } }
/// <summary> /// Dispatches a write operation. /// </summary> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> private void DispatchWrite(StorageAsyncResult<NullType> asyncResult) { if (this.internalBuffer.Length == 0) { if (asyncResult != null) { asyncResult.OnComplete(this.lastException); } return; } MultiBufferMemoryStream bufferToUpload = this.internalBuffer; this.internalBuffer = new MultiBufferMemoryStream(this.Blob.ServiceClient.BufferManager); bufferToUpload.Seek(0, SeekOrigin.Begin); string bufferMD5 = null; if (this.blockMD5 != null) { bufferMD5 = this.blockMD5.ComputeHash(); this.blockMD5.Dispose(); this.blockMD5 = new MD5Wrapper(); } if (this.blockBlob != null) { string blockId = this.GetCurrentBlockId(); this.blockList.Add(blockId); this.WriteBlock(bufferToUpload, blockId, bufferMD5, asyncResult); } else { if ((bufferToUpload.Length % Constants.PageSize) != 0) { this.lastException = new IOException(SR.InvalidPageSize); throw this.lastException; } long offset = this.currentPageOffset; this.currentPageOffset += bufferToUpload.Length; this.WritePages(bufferToUpload, offset, bufferMD5, asyncResult); } }
private void PutBlockHandler(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult<NullType> storageAsyncResult) { lock (storageAsyncResult.CancellationLockerObject) { ICancellableAsyncResult result = Executor.BeginExecuteAsync( this.PutBlockImpl(blockData, blockId, contentMD5, accessCondition, options), options.RetryPolicy, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { Executor.EndExecuteAsync<NullType>(ar); storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* asyncState */); storageAsyncResult.CancelDelegate = result.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } } }
public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { string containerName; string listingPrefix; CloudBlobClient.ParseUserPrefix(prefix, out containerName, out listingPrefix); CloudBlobContainer container = this.GetContainerReference(containerName); StorageAsyncResult<BlobResultSegment> result = new StorageAsyncResult<BlobResultSegment>(callback, state); ICancellableAsyncResult asyncResult = container.BeginListBlobsSegmented( listingPrefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, ar => { result.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { result.Result = container.EndListBlobsSegmented(ar); result.OnComplete(); } catch (Exception e) { result.OnComplete(e); } }, null /* state */); result.CancelDelegate = asyncResult.Cancel; return result; }
private void UploadFromStreamHandler(Stream source, long? length, string contentMD5, AccessCondition accessCondition, OperationContext operationContext, BlobRequestOptions options, StorageAsyncResult<NullType> storageAsyncResult) { ICancellableAsyncResult result = Executor.BeginExecuteAsync( this.PutBlobImpl(source, length, contentMD5, accessCondition, options), options.RetryPolicy, operationContext, ar => { storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); try { Executor.EndExecuteAsync<NullType>(ar); storageAsyncResult.OnComplete(); } catch (Exception e) { storageAsyncResult.OnComplete(e); } }, null /* asyncState */); storageAsyncResult.CancelDelegate = result.Cancel; if (storageAsyncResult.CancelRequested) { storageAsyncResult.Cancel(); } }
/// <summary> /// Ends an asynchronous write operation. /// </summary> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> public override void EndWrite(IAsyncResult asyncResult) { StorageAsyncResult <NullType> result = (StorageAsyncResult <NullType>)asyncResult; result.End(); }
public ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) { CommonUtility.AssertNotNull("path", path); FileStream fileStream = new FileStream(path, mode, FileAccess.Read); StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state) { OperationState = fileStream }; try { ICancellableAsyncResult asyncResult = this.BeginUploadFromStream(fileStream, accessCondition, options, operationContext, this.UploadFromFileCallback, storageAsyncResult); storageAsyncResult.CancelDelegate = asyncResult.Cancel; return storageAsyncResult; } catch (Exception) { fileStream.Dispose(); throw; } }
/// <summary> /// Ends an asynchronous copy operation. /// </summary> /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param> public void EndFastCopyTo(IAsyncResult asyncResult) { StorageAsyncResult <NullType> result = (StorageAsyncResult <NullType>)asyncResult; result.End(); }