Ejemplo n.º 1
0
        public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            CommonUtils.AssertNotNull("source", source);
            this.attributes.AssertNoSnapshot();
            if (!source.CanSeek)
            {
                throw new InvalidOperationException();
            }

            long size = source.Length - source.Position;
            if ((size % Constants.PageSize) != 0)
            {
                throw new ArgumentException(SR.InvalidPageSize, "source");
            }

            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient);

            DateTime? expiryTime = modifiedOptions.MaximumExecutionTime.HasValue
                ? DateTime.Now + modifiedOptions.MaximumExecutionTime.Value
                : (DateTime?)null;

            OperationContext tempOperationContext = new OperationContext();
            ExecutionState<NullType> executionState = new ExecutionState<NullType>(null /* cmd */, modifiedOptions.RetryPolicy, tempOperationContext);
            ChainedAsyncResult<NullType> chainedResult = new ChainedAsyncResult<NullType>(callback, state);

            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult result = this.BeginOpenWrite(
                    size,
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                        lock (chainedResult.CancellationLockerObject)
                        {
                            chainedResult.CancelDelegate = null;
                            try
                            {
                                Stream blobStream = this.EndOpenWrite(ar);

                                source.WriteToAsync(
                                    blobStream,
                                    null /* maxLength */,
                                    expiryTime,
                                    false,
                                    executionState,
                                    tempOperationContext,
                                    null /* streamCopyState */,
                                    completedState =>
                                    {
                                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);

                                        try
                                        {
                                            blobStream.Close();
                                            chainedResult.OnComplete(executionState.ExceptionRef);
                                        }
                                        catch (Exception e)
                                        {
                                            chainedResult.OnComplete(e);
                                        }
                                    });

                                chainedResult.CancelDelegate = executionState.Cancel;
                                if (chainedResult.CancelRequested)
                                {
                                    chainedResult.Cancel();
                                }
                            }
                            catch (Exception e)
                            {
                                chainedResult.OnComplete(e);
                            }
                        }
                    },
                    null /* state */);

                chainedResult.CancelDelegate = result.Cancel;
                if (chainedResult.CancelRequested)
                {
                    chainedResult.Cancel();
                }
            }

            return chainedResult;
        }
Ejemplo n.º 2
0
 public ICancellableAsyncResult BeginDeleteIfExists(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
 {
     BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient);
     ChainedAsyncResult<bool> chainedResult = new ChainedAsyncResult<bool>(callback, state)
     {
         RequestOptions = modifiedOptions,
         OperationContext = operationContext,
         CompletedSynchronously = true,
     };
     this.DeleteIfExistsHandler(accessCondition, options, operationContext, chainedResult);
     return chainedResult;
 }
Ejemplo n.º 3
0
        private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, ChainedAsyncResult<bool> chainedResult)
        {
            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult savedExistsResult = this.BeginExists(
                    options,
                    operationContext,
                    existsResult =>
                    {
                        chainedResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously);
                        lock (chainedResult.CancellationLockerObject)
                        {
                            chainedResult.CancelDelegate = null;
                            try
                            {
                                bool exists = this.EndExists(existsResult);
                                if (!exists)
                                {
                                    chainedResult.Result = false;
                                    chainedResult.OnComplete();
                                    return;
                                }

                                ICancellableAsyncResult savedDeleteResult = this.BeginDelete(
                                    deleteSnapshotsOption,
                                    accessCondition,
                                    options,
                                    operationContext,
                                    deleteResult =>
                                    {
                                        chainedResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously);
                                        chainedResult.CancelDelegate = null;
                                        try
                                        {
                                            this.EndDelete(deleteResult);
                                            chainedResult.Result = true;
                                            chainedResult.OnComplete();
                                        }
                                        catch (StorageException e)
                                        {
                                            if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound)
                                            {
                                                chainedResult.Result = false;
                                                chainedResult.OnComplete();
                                            }
                                            else
                                            {
                                                chainedResult.OnComplete(e);
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            chainedResult.OnComplete(e);
                                        }
                                    },
                                    null /* state */);

                                chainedResult.CancelDelegate = savedDeleteResult.Cancel;
                                if (chainedResult.CancelRequested)
                                {
                                    chainedResult.Cancel();
                                }
                            }
                            catch (Exception e)
                            {
                                chainedResult.OnComplete(e);
                            }
                        }
                    },
                    null /* state */);

                chainedResult.CancelDelegate = savedExistsResult.Cancel;
                if (chainedResult.CancelRequested)
                {
                    chainedResult.Cancel();
                }
            }
        }
Ejemplo n.º 4
0
        public ICancellableAsyncResult BeginWritePages(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient);
            bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value;
            operationContext = operationContext ?? new OperationContext();
            ChainedAsyncResult<NullType> chainedResult = new ChainedAsyncResult<NullType>(callback, state);

            if (pageData.CanSeek && !requiresContentMD5)
            {
                this.WritePagesHandler(pageData, startOffset, contentMD5, accessCondition, modifiedOptions, operationContext, chainedResult);
            }
            else
            {
                DateTime? expiryTime = modifiedOptions.MaximumExecutionTime.HasValue
                    ? DateTime.Now + modifiedOptions.MaximumExecutionTime.Value
                    : (DateTime?)null;

                OperationContext tempOperationContext = new OperationContext();
                ExecutionState<NullType> executionState = new ExecutionState<NullType>(null /* cmd */, modifiedOptions.RetryPolicy, tempOperationContext);
                chainedResult.CancelDelegate = executionState.Cancel;

                Stream seekableStream;
                Stream writeToStream;
                if (pageData.CanSeek)
                {
                    seekableStream = pageData;
                    writeToStream = Stream.Null;
                }
                else
                {
                    seekableStream = new MemoryStream();
                    writeToStream = seekableStream;
                }

                long startPosition = seekableStream.Position;
                StreamDescriptor streamCopyState = new StreamDescriptor();
                pageData.WriteToAsync(
                    writeToStream,
                    Constants.MaxBlockSize,
                    expiryTime,
                    requiresContentMD5,
                    executionState,
                    tempOperationContext,
                    streamCopyState,
                    _ =>
                    {
                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);

                        if (executionState.ExceptionRef != null)
                        {
                            chainedResult.OnComplete(executionState.ExceptionRef);
                        }
                        else
                        {
                            try
                            {
                                if (requiresContentMD5)
                                {
                                    contentMD5 = streamCopyState.Md5;
                                }

                                seekableStream.Position = startPosition;
                                this.WritePagesHandler(seekableStream, startOffset, contentMD5, accessCondition, modifiedOptions, operationContext, chainedResult);
                            }
                            catch (Exception e)
                            {
                                chainedResult.OnComplete(e);
                            }
                        }
                    });
            }

            return chainedResult;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Starts an asynchronous WritePages operation as soon as the parallel
        /// operation semaphore becomes available.
        /// </summary>
        /// <param name="pageData">Data to be uploaded</param>
        /// <param name="offset">Offset within the page blob</param>
        /// <param name="contentMD5">MD5 hash of the data to be uploaded</param>
        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
        private void WritePages(Stream pageData, long offset, string contentMD5, ChainedAsyncResult<NullType> asyncResult)
        {
            Interlocked.Increment(ref this.pendingWrites);
            this.noPendingWritesEvent.Reset();

            bool completedSynchronously = this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
                {
                    if (asyncResult != null)
                    {
                        asyncResult.UpdateCompletedSynchronously(calledSynchronously);
                    }

                    try
                    {
                        this.pageBlob.BeginWritePages(
                            pageData,
                            offset,
                            contentMD5,
                            this.accessCondition,
                            this.options,
                            this.operationContext,
                            ar =>
                            {
                                try
                                {
                                    this.pageBlob.EndWritePages(ar);
                                }
                                catch (Exception e)
                                {
                                    this.lastException = e;
                                }

                                // This must be called before calling the user's callback
                                // in case the callback is blocking.
                                if (Interlocked.Decrement(ref this.pendingWrites) == 0)
                                {
                                    this.noPendingWritesEvent.Set();
                                }

                                this.parallelOperationSemaphore.Release();

                                // Do not try-catch this portion, as we are done anyway.
                                // We should let the user handle the exception.
                                if (!calledSynchronously && (asyncResult != null))
                                {
                                    // End the async result
                                    asyncResult.OnComplete(this.lastException);
                                }
                            },
                            null /* state */);
                    }
                    catch (Exception e)
                    {
                        this.lastException = e;

                        // End the async result
                        if (asyncResult != null)
                        {
                            asyncResult.OnComplete(e);
                        }
                    }
                });

            if (completedSynchronously && (asyncResult != null))
            {
                asyncResult.OnComplete();
            }
        }
Ejemplo n.º 6
0
        /// <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)
        {
            CommonUtils.AssertNotNull("buffer", buffer);
            CommonUtils.AssertInBounds("offset", offset, 0, buffer.Length);
            CommonUtils.AssertInBounds("count", count, 0, buffer.Length - offset);

            ChainedAsyncResult<int> chainedResult = new ChainedAsyncResult<int>(callback, state);

            if (this.lastException != null)
            {
                chainedResult.OnComplete(this.lastException);
            }
            else
            {
                if (!this.isLengthAvailable)
                {
                    this.blob.BeginFetchAttributes(
                        this.accessCondition,
                        this.options,
                        this.operationContext,
                        ar =>
                        {
                            chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                            try
                            {
                                this.blob.EndFetchAttributes(ar);
                            }
                            catch (Exception e)
                            {
                                this.lastException = e;
                                chainedResult.OnComplete(this.lastException);
                                return;
                            }

                            this.LockToETag();
                            this.isLengthAvailable = true;

                            if (string.IsNullOrEmpty(this.blob.Properties.ContentMD5))
                            {
                                this.blobMD5 = null;
                            }

                            this.DispatchRead(chainedResult, buffer, offset, count);
                        },
                        null /* state */);
                }
                else
                {
                    this.DispatchRead(chainedResult, buffer, offset, count);
                }
            }

            return chainedResult;
        }
 /// <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)
 {
     ChainedAsyncResult<Stream> chainedResult = new ChainedAsyncResult<Stream>(callback, state)
     {
         CompletedSynchronously = true,
         Result = this.OpenWrite(accessCondition, options, operationContext),
     };
     chainedResult.OnComplete();
     return chainedResult;
 }
Ejemplo n.º 8
0
        /// <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)
        {
            CommonUtils.AssertNotNull("buffer", buffer);
            CommonUtils.AssertInBounds("offset", offset, 0, buffer.Length);
            CommonUtils.AssertInBounds("count", count, 0, buffer.Length - offset);

            if (this.blobMD5 != null)
            {
                this.blobMD5.UpdateHash(buffer, offset, count);
            }

            ChainedAsyncResult<NullType> chainedResult = new ChainedAsyncResult<NullType>(callback, state);
            ChainedAsyncResult<NullType> currentChainedResult = chainedResult;

            this.currentOffset += count;
            bool dispatched = false;
            if (this.lastException == null)
            {
                while (count > 0)
                {
                    int maxBytesToWrite = this.Blob.StreamWriteSizeInBytes - (int)this.buffer.Length;
                    int bytesToWrite = Math.Min(count, maxBytesToWrite);

                    this.buffer.Write(buffer, offset, bytesToWrite);
                    if (this.blockMD5 != null)
                    {
                        this.blockMD5.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)
            {
                chainedResult.OnComplete(this.lastException);
            }

            return chainedResult;
        }
        private void CreateIfNotExistsHandler(BlobRequestOptions options, OperationContext operationContext, ChainedAsyncResult<bool> chainedResult)
        {
            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult savedExistsResult = this.BeginExists(
                    options,
                    operationContext,
                    existsResult =>
                    {
                        chainedResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously);
                        lock (chainedResult.CancellationLockerObject)
                        {
                            chainedResult.CancelDelegate = null;
                            try
                            {
                                bool exists = this.EndExists(existsResult);
                                if (exists)
                                {
                                    chainedResult.Result = false;
                                    chainedResult.OnComplete();
                                    return;
                                }

                                ICancellableAsyncResult savedCreateResult = this.BeginCreate(
                                    options,
                                    operationContext,
                                    createResult =>
                                    {
                                        chainedResult.UpdateCompletedSynchronously(createResult.CompletedSynchronously);
                                        chainedResult.CancelDelegate = null;
                                        try
                                        {
                                            this.EndCreate(createResult);
                                            chainedResult.Result = true;
                                            chainedResult.OnComplete();
                                        }
                                        catch (StorageException e)
                                        {
                                            if ((e.RequestInformation.ExtendedErrorInformation != null) &&
                                                (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerAlreadyExists))
                                            {
                                                chainedResult.Result = false;
                                                chainedResult.OnComplete();
                                            }
                                            else
                                            {
                                                chainedResult.OnComplete(e);
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            chainedResult.OnComplete(e);
                                        }
                                    },
                                    null /* state */);

                                chainedResult.CancelDelegate = savedCreateResult.Cancel;
                                if (chainedResult.CancelRequested)
                                {
                                    chainedResult.Cancel();
                                }
                            }
                            catch (Exception e)
                            {
                                chainedResult.OnComplete(e);
                            }
                        }
                    },
                    null /* state */);

                chainedResult.CancelDelegate = savedExistsResult.Cancel;
                if (chainedResult.CancelRequested)
                {
                    chainedResult.Cancel();
                }
            }
        }
Ejemplo n.º 10
0
        private void PutBlockHandler(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, ChainedAsyncResult<NullType> chainedResult)
        {
            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult result = Executor.BeginExecuteAsync(
                    this.PutBlockImpl(blockData, blockId, contentMD5, accessCondition, options),
                    options.RetryPolicy,
                    operationContext,
                    ar =>
                    {
                        try
                        {
                            Executor.EndExecuteAsync<NullType>(ar);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* asyncState */);

                chainedResult.CancelDelegate = result.Cancel;
                if (chainedResult.CancelRequested)
                {
                    chainedResult.Cancel();
                }
            }
        }
Ejemplo n.º 11
0
 public ICancellableAsyncResult BeginCreateIfNotExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
 {
     BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient);
     ChainedAsyncResult<bool> chainedResult = new ChainedAsyncResult<bool>(callback, state)
     {
         RequestOptions = modifiedOptions,
         OperationContext = operationContext,
     };
     this.CreateIfNotExistsHandler(options, operationContext, chainedResult);
     return chainedResult;
 }
Ejemplo n.º 12
0
        public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            this.attributes.AssertNoSnapshot();
            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient);

            ChainedAsyncResult<Stream> chainedResult = new ChainedAsyncResult<Stream>(callback, state);
            ICancellableAsyncResult result;
            if (size.HasValue)
            {
                result = this.BeginCreate(
                    size.Value,
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        try
                        {
                            this.EndCreate(ar);
                            chainedResult.CompletedSynchronously = ar.CompletedSynchronously;
                            chainedResult.Result = new BlobWriteStream(this, size.Value, accessCondition, modifiedOptions, operationContext);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* state */);
            }
            else
            {
                result = this.BeginFetchAttributes(
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        try
                        {
                            this.EndFetchAttributes(ar);
                            chainedResult.CompletedSynchronously = ar.CompletedSynchronously;
                            chainedResult.Result = new BlobWriteStream(this, this.Properties.Length, accessCondition, modifiedOptions, operationContext);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* state */);
            }

            chainedResult.CancelDelegate = result.Cancel;
            return chainedResult;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Starts an asynchronous WritePages operation as soon as the parallel
        /// operation semaphore becomes available.
        /// </summary>
        /// <param name="pageData">Data to be uploaded</param>
        /// <param name="offset">Offset within the page blob</param>
        /// <param name="contentMD5">MD5 hash of the data to be uploaded</param>
        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
        private void WritePages(Stream pageData, long offset, string contentMD5, ChainedAsyncResult <NullType> asyncResult)
        {
            Interlocked.Increment(ref this.pendingWrites);
            this.noPendingWritesEvent.Reset();

            bool completedSynchronously = this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
            {
                if (asyncResult != null)
                {
                    asyncResult.UpdateCompletedSynchronously(calledSynchronously);
                }

                try
                {
                    this.pageBlob.BeginWritePages(
                        pageData,
                        offset,
                        contentMD5,
                        this.accessCondition,
                        this.options,
                        this.operationContext,
                        ar =>
                    {
                        try
                        {
                            this.pageBlob.EndWritePages(ar);
                        }
                        catch (Exception e)
                        {
                            this.lastException = e;
                        }

                        // This must be called before calling the user's callback
                        // in case the callback is blocking.
                        if (Interlocked.Decrement(ref this.pendingWrites) == 0)
                        {
                            this.noPendingWritesEvent.Set();
                        }

                        this.parallelOperationSemaphore.Release();

                        // Do not try-catch this portion, as we are done anyway.
                        // We should let the user handle the exception.
                        if (!calledSynchronously && (asyncResult != null))
                        {
                            // End the async result
                            asyncResult.OnComplete(this.lastException);
                        }
                    },
                        null /* state */);
                }
                catch (Exception e)
                {
                    this.lastException = e;

                    // End the async result
                    if (asyncResult != null)
                    {
                        asyncResult.OnComplete(e);
                    }
                }
            });

            if (completedSynchronously && (asyncResult != null))
            {
                asyncResult.OnComplete();
            }
        }
Ejemplo n.º 14
0
        private void UploadFromStreamHandler(Stream source, string contentMD5, AccessCondition accessCondition, OperationContext operationContext, BlobRequestOptions options, ChainedAsyncResult<NullType> chainedResult)
        {
            ICancellableAsyncResult result = Executor.BeginExecuteAsync(
                this.PutBlobImpl(source, contentMD5, accessCondition, options),
                options.RetryPolicy,
                operationContext,
                ar =>
                {
                    chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                    try
                    {
                        Executor.EndExecuteAsync<NullType>(ar);
                        chainedResult.OnComplete();
                    }
                    catch (Exception e)
                    {
                        chainedResult.OnComplete(e);
                    }
                },
                null /* asyncState */);

            chainedResult.CancelDelegate = result.Cancel;
            if (chainedResult.CancelRequested)
            {
                chainedResult.Cancel();
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Dispatches a read operation that either reads from the cache or makes a call to
        /// the server.
        /// </summary>
        /// <param name="chainedResult">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>
        /// <remarks>Even though this code looks like it can run in parallel, the semaphore only allows
        /// 1 active read. This is required because of caching.</remarks>
        private void DispatchRead(ChainedAsyncResult <int> chainedResult, byte[] buffer, int offset, int count)
        {
            if ((this.currentOffset == this.Length) || (count == 0))
            {
                chainedResult.Result = 0;
                chainedResult.OnComplete();
            }
            else
            {
                this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
                {
                    try
                    {
                        // If the buffer is already consumed, dispatch another read.
                        if (this.buffer.Position == this.buffer.Length)
                        {
                            int readSize = (int)Math.Min(this.blob.StreamMinimumReadSizeInBytes, this.Length - this.currentOffset);
                            if (this.options.UseTransactionalMD5.Value)
                            {
                                readSize = Math.Min(readSize, Constants.MaxBlockSize);
                            }

                            this.buffer.SetLength(0);
                            this.blob.BeginDownloadRangeToStream(
                                this.buffer,
                                this.currentOffset,
                                readSize,
                                this.accessCondition,
                                this.options,
                                this.operationContext,
                                ar =>
                            {
                                try
                                {
                                    this.blob.EndDownloadRangeToStream(ar);
                                }
                                catch (Exception e)
                                {
                                    this.lastException = e;
                                }

                                if (this.lastException == null)
                                {
                                    this.buffer.Seek(0, SeekOrigin.Begin);
                                    this.LockToETag();

                                    // Read as much as we can from the buffer.
                                    int result           = this.buffer.Read(buffer, offset, count);
                                    this.currentOffset  += result;
                                    chainedResult.Result = result;
                                    this.VerifyBlobMD5(buffer, offset, result);
                                }

                                // Calling this here will make reentrancy safer, as the user
                                // does not yet know the operation has completed.
                                this.parallelOperationSemaphore.Release();

                                // End the async result
                                chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
                                chainedResult.OnComplete(this.lastException);
                            },
                                null /* state */);
                        }
                        else
                        {
                            // Read as much as we can from the buffer.
                            int result           = this.buffer.Read(buffer, offset, count);
                            this.currentOffset  += result;
                            chainedResult.Result = result;
                            this.VerifyBlobMD5(buffer, offset, result);

                            // Calling this here will make reentrancy safer, as the user
                            // does not yet know the operation has completed.
                            this.parallelOperationSemaphore.Release();

                            // End the async result
                            chainedResult.UpdateCompletedSynchronously(calledSynchronously);
                            chainedResult.OnComplete(this.lastException);
                        }
                    }
                    catch (Exception e)
                    {
                        this.lastException = e;

                        // End the async result
                        chainedResult.UpdateCompletedSynchronously(calledSynchronously);
                        chainedResult.OnComplete(this.lastException);
                    }
                });
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Begins an asynchronous request to delete the queue if it already exists.
        /// </summary>
        /// <param name="options">An <see cref="QueueRequestOptions"/> 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. This object is used to track requests to the storage service, and to provide additional runtime information about the 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 BeginDeleteIfExists(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient);
            operationContext = operationContext ?? new OperationContext();

            ChainedAsyncResult<bool> chainedResult = new ChainedAsyncResult<bool>(callback, state)
            {
                RequestOptions = modifiedOptions,
                OperationContext = operationContext,
            };

            operationContext.OperationExpiryTime = modifiedOptions.MaximumExecutionTime.HasValue
                                                       ? DateTime.Now + modifiedOptions.MaximumExecutionTime.Value
                                                       : (DateTime?)null;

            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult currentRes = this.BeginExists(modifiedOptions, operationContext, this.DeleteIfExistsHandler, chainedResult);
                chainedResult.CancelDelegate = currentRes.Cancel;

                // Check if cancellation was requested prior to begin
                if (chainedResult.CancelRequested)
                {
                    chainedResult.CancelDelegate();
                }
            }

            return chainedResult;
        }
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            ChainedAsyncResult<int> result = new ChainedAsyncResult<int>(callback, state);

            if (this.completeSynchronously)
            {
                result.UpdateCompletedSynchronously(this.completeSynchronously);
                result.Result = this.Read(buffer, offset, count);
                result.OnComplete();
            }
            else
            {
                ThreadPool.QueueUserWorkItem(_ =>
                    {
                        result.UpdateCompletedSynchronously(this.completeSynchronously);
                        result.Result = this.Read(buffer, offset, count);
                        result.OnComplete();
                    },
                    null);
            }

            return result;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Dispatches a write operation.
        /// </summary>
        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
        private void DispatchWrite(ChainedAsyncResult<NullType> asyncResult)
        {
            if (this.buffer.Length == 0)
            {
                return;
            }

            MemoryStream bufferToUpload = this.buffer;
            this.buffer = new MemoryStream(this.Blob.StreamWriteSizeInBytes);
            bufferToUpload.Seek(0, SeekOrigin.Begin);

            string bufferMD5 = null;
            if (this.blockMD5 != null)
            {
                bufferMD5 = this.blockMD5.ComputeHash();
                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)
                {
                    throw new IOException(SR.InvalidPageSize);
                }

                long offset = this.currentPageOffset;
                this.currentPageOffset += bufferToUpload.Length;
                this.WritePages(bufferToUpload, offset, bufferMD5, asyncResult);
            }
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            ChainedAsyncResult<NullType> result = new ChainedAsyncResult<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;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Dispatches a read operation that either reads from the cache or makes a call to
        /// the server.
        /// </summary>
        /// <param name="chainedResult">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>
        /// <remarks>Even though this code looks like it can run in parallel, the semaphore only allows
        /// 1 active read. This is required because of caching.</remarks>
        private void DispatchRead(ChainedAsyncResult<int> chainedResult, byte[] buffer, int offset, int count)
        {
            if ((this.currentOffset == this.Length) || (count == 0))
            {
                chainedResult.Result = 0;
                chainedResult.OnComplete();
            }
            else
            {
                this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
                    {
                        try
                        {
                            // If the buffer is already consumed, dispatch another read.
                            if (this.buffer.Position == this.buffer.Length)
                            {
                                int readSize = (int)Math.Min(this.blob.StreamMinimumReadSizeInBytes, this.Length - this.currentOffset);
                                if (this.options.UseTransactionalMD5.Value)
                                {
                                    readSize = Math.Min(readSize, Constants.MaxBlockSize);
                                }

                                this.buffer.SetLength(0);
                                this.blob.BeginDownloadRangeToStream(
                                    this.buffer,
                                    this.currentOffset,
                                    readSize,
                                    this.accessCondition,
                                    this.options,
                                    this.operationContext,
                                    ar =>
                                    {
                                        try
                                        {
                                            this.blob.EndDownloadRangeToStream(ar);
                                        }
                                        catch (Exception e)
                                        {
                                            this.lastException = e;
                                        }

                                        if (this.lastException == null)
                                        {
                                            this.buffer.Seek(0, SeekOrigin.Begin);
                                            this.LockToETag();

                                            // Read as much as we can from the buffer.
                                            int result = this.buffer.Read(buffer, offset, count);
                                            this.currentOffset += result;
                                            chainedResult.Result = result;
                                            this.VerifyBlobMD5(buffer, offset, result);
                                        }

                                        // Calling this here will make reentrancy safer, as the user
                                        // does not yet know the operation has completed.
                                        this.parallelOperationSemaphore.Release();

                                        // End the async result
                                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
                                        chainedResult.OnComplete(this.lastException);
                                    },
                                    null /* state */);
                            }
                            else
                            {
                                // Read as much as we can from the buffer.
                                int result = this.buffer.Read(buffer, offset, count);
                                this.currentOffset += result;
                                chainedResult.Result = result;
                                this.VerifyBlobMD5(buffer, offset, result);

                                // Calling this here will make reentrancy safer, as the user
                                // does not yet know the operation has completed.
                                this.parallelOperationSemaphore.Release();

                                // End the async result
                                chainedResult.UpdateCompletedSynchronously(calledSynchronously);
                                chainedResult.OnComplete(this.lastException);
                            }
                        }
                        catch (Exception e)
                        {
                            this.lastException = e;

                            // End the async result
                            chainedResult.UpdateCompletedSynchronously(calledSynchronously);
                            chainedResult.OnComplete(this.lastException);
                        }
                    });
            }
        }
 protected override void OnEndClose(IAsyncResult result)
 {
     ChainedAsyncResult.End(result);
 }
Ejemplo n.º 22
0
 public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
 {
     BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient);
     ChainedAsyncResult<bool> chainedResult = new ChainedAsyncResult<bool>(callback, state)
     {
         RequestOptions = modifiedOptions,
         OperationContext = operationContext,
     };
     this.DeleteIfExistsHandler(deleteSnapshotsOption, accessCondition, options, operationContext, chainedResult);
     return chainedResult;
 }
Ejemplo n.º 23
0
 void ICommunicationObject.EndClose(IAsyncResult result)
 {
     ChainedAsyncResult.End(result);
 }
Ejemplo n.º 24
0
        public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            this.attributes.AssertNoSnapshot();
            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient);
            bool createNew = size.HasValue;

            ChainedAsyncResult<Stream> chainedResult = new ChainedAsyncResult<Stream>(callback, state);
            ICancellableAsyncResult result;
            if (createNew)
            {
                result = this.BeginCreate(
                    size.Value,
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                        try
                        {
                            this.EndCreate(ar);

                            if (accessCondition != null)
                            {
                                accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId);
                            }

                            chainedResult.Result = new BlobWriteStream(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* state */);
            }
            else
            {
                if (modifiedOptions.StoreBlobContentMD5.Value)
                {
                    throw new ArgumentException(SR.MD5NotPossible);
                }

                result = this.BeginFetchAttributes(
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                        try
                        {
                            this.EndFetchAttributes(ar);

                            if (accessCondition != null)
                            {
                                accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId);
                            }

                            chainedResult.Result = new BlobWriteStream(this, this.Properties.Length, createNew, accessCondition, modifiedOptions, operationContext);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* state */);
            }

            chainedResult.CancelDelegate = result.Cancel;
            return chainedResult;
        }
Ejemplo n.º 25
0
        /// <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();
            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient);

            ChainedAsyncResult<Stream> chainedResult = new ChainedAsyncResult<Stream>(callback, state);
            if ((accessCondition != null) && accessCondition.IsConditional)
            {
                ICancellableAsyncResult result = this.BeginFetchAttributes(
                    accessCondition,
                    modifiedOptions,
                    operationContext,
                    ar =>
                    {
                        chainedResult.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
                            {
                                chainedResult.OnComplete(e);
                            }
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }

                        chainedResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext);
                        chainedResult.OnComplete();
                    },
                    null /* state */);

                chainedResult.CancelDelegate = result.Cancel;
            }
            else
            {
                chainedResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext);
                chainedResult.OnComplete();
            }

            return chainedResult;
        }
Ejemplo n.º 26
0
        private void WritePagesHandler(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, ChainedAsyncResult<NullType> chainedResult)
        {
            lock (chainedResult.CancellationLockerObject)
            {
                ICancellableAsyncResult result = Executor.BeginExecuteAsync(
                    this.PutPageImpl(pageData, startOffset, contentMD5, accessCondition, options),
                    options.RetryPolicy,
                    operationContext,
                    ar =>
                    {
                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);

                        try
                        {
                            Executor.EndExecuteAsync<NullType>(ar);
                            chainedResult.OnComplete();
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    },
                    null /* asyncState */);

                chainedResult.CancelDelegate = result.Cancel;
                if (chainedResult.CancelRequested)
                {
                    chainedResult.Cancel();
                }
            }
        }
Ejemplo n.º 27
0
        public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state)
        {
            CommonUtils.AssertNotNull("source", source);
            this.attributes.AssertNoSnapshot();
            BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient);

            DateTime? expiryTime = modifiedOptions.MaximumExecutionTime.HasValue
                ? DateTime.Now + modifiedOptions.MaximumExecutionTime.Value
                : (DateTime?)null;

            OperationContext tempOperationContext = new OperationContext();
            ExecutionState<NullType> executionState = new ExecutionState<NullType>(null /* cmd */, modifiedOptions.RetryPolicy, tempOperationContext);
            ChainedAsyncResult<NullType> chainedResult = new ChainedAsyncResult<NullType>(callback, state)
            {
                CancelDelegate = executionState.Cancel,
            };

            if ((this.ServiceClient.ParallelOperationThreadCount == 1) &&
                source.CanSeek &&
                ((source.Length - source.Position) <= this.ServiceClient.SingleBlobUploadThresholdInBytes))
            {
                if (modifiedOptions.StoreBlobContentMD5.Value)
                {
                    long startPosition = source.Position;
                    StreamDescriptor streamCopyState = new StreamDescriptor();
                    source.WriteToAsync(
                        Stream.Null,
                        null /* maxLength */,
                        expiryTime,
                        true,
                        executionState,
                        tempOperationContext,
                        streamCopyState,
                        completedState =>
                        {
                            chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);

                            try
                            {
                                lock (chainedResult.CancellationLockerObject)
                                {
                                    chainedResult.CancelDelegate = null;
                                    if (completedState.ExceptionRef != null)
                                    {
                                        chainedResult.OnComplete(completedState.ExceptionRef);
                                    }
                                    else
                                    {
                                        source.Position = startPosition;
                                        UploadFromStreamHandler(source, streamCopyState.Md5, accessCondition, operationContext, modifiedOptions, chainedResult);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                chainedResult.OnComplete(e);
                            }
                        });
                }
                else
                {
                    this.UploadFromStreamHandler(source, null /* contentMD5 */, accessCondition, operationContext, modifiedOptions, chainedResult);
                }
            }
            else
            {
                Stream blobStream = this.OpenWrite(accessCondition, modifiedOptions, operationContext);

                source.WriteToAsync(
                    blobStream,
                    null /* maxLength */,
                    expiryTime,
                    false,
                    executionState,
                    tempOperationContext,
                    null /* streamCopyState */,
                    completedState =>
                    {
                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);

                        try
                        {
                            blobStream.Close();
                            chainedResult.OnComplete(executionState.ExceptionRef);
                        }
                        catch (Exception e)
                        {
                            chainedResult.OnComplete(e);
                        }
                    });
            }

            return chainedResult;
        }
Ejemplo n.º 28
0
        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);
            ChainedAsyncResult<BlobResultSegment> result = new ChainedAsyncResult<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;
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Starts an asynchronous WritePages operation as soon as the parallel
        /// operation semaphore becomes available.
        /// </summary>
        /// <param name="pageData">Data to be uploaded</param>
        /// <param name="offset">Offset within the page blob</param>
        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
        private void WritePages(Stream pageData, long offset, string contentMD5, ChainedAsyncResult <NullType> asyncResult)
        {
            Interlocked.Increment(ref this.pendingWrites);
            this.noPendingWritesEvent.Reset();

            bool completedSynchronously = this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
            {
                try
                {
                    this.pageBlob.BeginWritePages(
                        pageData,
                        offset,
                        contentMD5,
                        this.accessCondition,
                        this.options,
                        this.operationContext,
                        ar =>
                    {
                        try
                        {
                            this.pageBlob.EndWritePages(ar);
                        }
                        catch (Exception e)
                        {
                            this.lastException = e;
                        }

                        try
                        {
                            if (!calledSynchronously && (asyncResult != null))
                            {
                                // End the async result
                                asyncResult.CompletedSynchronously = ar.CompletedSynchronously;
                                asyncResult.OnComplete(this.lastException);
                            }
                        }
                        catch (Exception)
                        {
                            // If user's callback throws an exception, we want to
                            // ignore and continue.
                        }
                        finally
                        {
                            if (Interlocked.Decrement(ref this.pendingWrites) == 0)
                            {
                                this.noPendingWritesEvent.Set();
                            }

                            this.parallelOperationSemaphore.Release();
                        }
                    },
                        null /* state */);
                }
                catch (Exception e)
                {
                    this.lastException = e;

                    // End the async result
                    asyncResult.CompletedSynchronously = calledSynchronously;
                    asyncResult.OnComplete(e);
                }
            });

            if (completedSynchronously && asyncResult != null)
            {
                asyncResult.CompletedSynchronously = true;
                asyncResult.OnComplete();
            }
        }