public void CloudBlockBlobDownloadToStreamAPMCancel() { byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); using (MemoryStream originalBlob = new MemoryStream(buffer)) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndUploadFromStream(result); using (MemoryStream downloadedBlob = new MemoryStream()) { OperationContext operationContext = new OperationContext(); result = blob.BeginDownloadToStream(downloadedBlob, null, null, operationContext, ar => waitHandle.Set(), null); Thread.Sleep(100); result.Cancel(); waitHandle.WaitOne(); try { blob.EndDownloadToStream(result); } catch (StorageException ex) { Assert.AreEqual("A task was canceled.", ex.Message); Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 306); Assert.AreEqual(ex.RequestInformation.HttpStatusMessage, null); } TestHelper.AssertNAttempts(operationContext, 1); } } } } finally { container.DeleteIfExists(); } }
public void RetryDelayShouldBeCancellable() { using (ManualResetEvent responseWaitHandle = new ManualResetEvent(false), callbackWaitHandle = new ManualResetEvent(false)) { BlobRequestOptions options = new BlobRequestOptions(); options.RetryPolicy = new OldStyleAlwaysRetry(TimeSpan.FromMinutes(1), 1); OperationContext context = new OperationContext(); context.ResponseReceived += (sender, e) => responseWaitHandle.Set(); CloudBlobClient blobClient = GenerateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference("test" + DateTime.UtcNow.Ticks.ToString()); ICancellableAsyncResult asyncResult = container.BeginFetchAttributes(null, options, context, ar => { try { container.EndFetchAttributes(ar); } catch (Exception) { // This is expected, because we went for an invalid domain name. } callbackWaitHandle.Set(); }, null); responseWaitHandle.WaitOne(); Thread.Sleep(10 * 1000); Stopwatch stopwatch = Stopwatch.StartNew(); asyncResult.Cancel(); callbackWaitHandle.WaitOne(); stopwatch.Stop(); Assert.IsTrue(stopwatch.Elapsed < TimeSpan.FromSeconds(10), stopwatch.Elapsed.ToString()); Assert.AreEqual(1, context.RequestResults.Count); } }
/// <summary> /// Deletes the table if it exists asynchronously. /// </summary> /// <param name="cloudTable">Cloud table.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// <c>true</c> if the table was deleted; otherwise, <c>false</c>. /// </returns> public static Task <bool> DeleteIfExistsAsync( this CloudTable cloudTable, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = cloudTable.BeginDeleteIfExists(null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task <bool> .Factory.FromAsync( asyncResult, result => { registration.Dispose(); return cloudTable.EndDeleteIfExists(result); })); }
/// <summary> /// Sets the permissions settings for the table asynchronously. /// </summary> /// <param name="cloudTable">Cloud table.</param> /// <param name="tablePermissions"> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TablePermissions" /> object that represents the permissions to set. /// </param> /// <param name="cancellationToken">Cancellation token.</param> public static Task SetPermissionsAsync( this CloudTable cloudTable, TablePermissions tablePermissions, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = cloudTable.BeginSetPermissions(tablePermissions, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task.Factory.FromAsync( asyncResult, result => { registration.Dispose(); cloudTable.EndSetPermissions(result); })); }
/// <summary> /// Executes an operation to query a table in segmented mode asynchronously. /// </summary> /// <typeparam name="TElement">The entity type of the query.</typeparam> /// <typeparam name="TR"> /// The type into which the <see cref="T:Microsoft.WindowsAzure.Storage.Table.EntityResolver" /> will project the query results. /// </typeparam> /// <param name="cloudTable">Cloud table.</param> /// <param name="tableQuery"> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableQuery" /> instance specifying the table to query and the query parameters to use, specialized for a type <c>TElement</c>. /// </param> /// <param name="entityResolver"> /// An <see cref="T:Microsoft.WindowsAzure.Storage.Table.EntityResolver" /> instance which creates a projection of the table query result entities into the specified type <c>R</c>. /// </param> /// <param name="continuationToken"> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableContinuationToken" /> object representing a continuation token from the server when the operation returns a partial result. /// </param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableQuerySegment`1" /> containing the projection into type <c>R</c> of the results of executing the query. /// </returns> public static Task <TableQuerySegment <TR> > ExecuteQuerySegmentedAsync <TElement, TR>( this CloudTable cloudTable, TableQuery <TElement> tableQuery, EntityResolver <TR> entityResolver, TableContinuationToken continuationToken, CancellationToken cancellationToken = default(CancellationToken)) where TElement : ITableEntity, new() { ICancellableAsyncResult asyncResult = cloudTable.BeginExecuteQuerySegmented( tableQuery, entityResolver, continuationToken, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task <TableQuerySegment <TR> > .Factory.FromAsync( asyncResult, result => { registration.Dispose(); return cloudTable.EndExecuteQuerySegmented <TElement, TR>(result); })); }
/// <summary> /// Executes an operation to query a table in segmented mode asynchronously. /// </summary> /// <param name="cloudTable">Cloud table.</param> /// <param name="tableQuery"> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableQuery" /> instance specifying the table to query and the query parameters to use, specialized for a type <c>TElement</c>. /// </param> /// <param name="continuationToken"> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableContinuationToken" /> object representing a continuation token from the server when the operation returns a partial result. /// </param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// A <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableQuerySegment`1" /> containing the projection into type <c>R</c> of the results of executing the query. /// </returns> public static Task <TableQuerySegment <DynamicTableEntity> > ExecuteQuerySegmentedAsync( this CloudTable cloudTable, TableQuery tableQuery, TableContinuationToken continuationToken, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = cloudTable.BeginExecuteQuerySegmented( tableQuery, continuationToken, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task <TableQuerySegment <DynamicTableEntity> > .Factory.FromAsync( asyncResult, result => { registration.Dispose(); return cloudTable.EndExecuteQuerySegmented(result); })); }
/// <summary> /// Creates a table asynchronously. /// </summary> /// <param name="cloudTable">Cloud table.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Task.</returns> public static Task CreateAsync( this CloudTable cloudTable, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = cloudTable.BeginCreate(null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task.Factory.FromAsync( asyncResult, result => { registration.Dispose(); cloudTable.EndCreate(result); })); }
/// <summary> /// Executes a batch of operations on a table asynchronously. /// </summary> /// <param name="cloudTable">Cloud table.</param> /// <param name="tableBatchOperation"> /// The <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableBatchOperation" /> object representing the operations to execute on the table. /// </param> /// <param name="cancellationToken">Cancalltion token.</param> /// <returns> /// An enumerable collection of <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableResult" /> objects that contains the results, in order, of each operation in the /// <see cref="T:Microsoft.WindowsAzure.Storage.Table.TableBatchOperation" /> /// on the table. /// </returns> public static Task <IList <TableResult> > ExecuteBatchAsync( this CloudTable cloudTable, TableBatchOperation tableBatchOperation, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = cloudTable.BeginExecuteBatch(tableBatchOperation, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task <IList <TableResult> > .Factory.FromAsync( asyncResult, result => { registration.Dispose(); return cloudTable.EndExecuteBatch(result); })); }
/// <summary> /// Returns an enumerable collection of tables in the storage account asynchronously. /// </summary> /// <param name="tableClient">Cloud table client.</param> /// <param name="prefix">The table name prefix.</param> /// <param name="maxResults"> /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is zero the maximum possible number of results will be returned, up to 5000. /// </param> /// <param name="continuationToken">Continuation token.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// An enumerable collection of tables that are retrieved lazily. /// </returns> public static Task <TableResultSegment> ListTablesSegmentedAsync( this CloudTableClient tableClient, string prefix, int?maxResults, TableContinuationToken continuationToken, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = tableClient.BeginListTablesSegmented(prefix, maxResults, continuationToken, null, null, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task <TableResultSegment> .Factory.FromAsync( asyncResult, result => { registration.Dispose(); return tableClient.EndListTablesSegmented(result); })); }
/// <summary> /// Sets the properties of the table service asynchronously. /// </summary> /// <param name="tableClient">Cloud table client.</param> /// <param name="serviceProperties">The table service properties.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Task.</returns> public static Task SetServicePropertiesAsync( this CloudTableClient tableClient, ServiceProperties serviceProperties, CancellationToken cancellationToken = default(CancellationToken)) { ICancellableAsyncResult asyncResult = tableClient.BeginSetServiceProperties(serviceProperties, null, null); CancellationTokenRegistration registration = cancellationToken.Register(p => asyncResult.Cancel(), null); return(Task.Factory.FromAsync( asyncResult, result => { registration.Dispose(); tableClient.EndSetServiceProperties(result); })); }
public void FileWriteStreamFlushTestAPM() { byte[] buffer = GetRandomBuffer(512 * 1024); CloudFileShare share = GetRandomShareReference(); try { share.Create(); CloudFile file = share.GetRootDirectoryReference().GetFileReference("file1"); file.StreamWriteSizeInBytes = 1 * 1024 * 1024; using (MemoryStream wholeFile = new MemoryStream()) { FileRequestOptions options = new FileRequestOptions() { StoreFileContentMD5 = true }; OperationContext opContext = new OperationContext(); using (CloudFileStream fileStream = file.OpenWrite(4 * buffer.Length, null, options, opContext)) { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { IAsyncResult result; for (int i = 0; i < 3; i++) { result = fileStream.BeginWrite( buffer, 0, buffer.Length, ar => waitHandle.Set(), null); waitHandle.WaitOne(); fileStream.EndWrite(result); wholeFile.Write(buffer, 0, buffer.Length); } Assert.AreEqual(2, opContext.RequestResults.Count); ICancellableAsyncResult cancellableResult = fileStream.BeginFlush( ar => waitHandle.Set(), null); Assert.IsFalse(cancellableResult.IsCompleted); cancellableResult.Cancel(); waitHandle.WaitOne(); fileStream.EndFlush(cancellableResult); result = fileStream.BeginFlush( ar => waitHandle.Set(), null); Assert.IsFalse(result.IsCompleted); TestHelper.ExpectedException <InvalidOperationException>( () => fileStream.BeginFlush(null, null), null); waitHandle.WaitOne(); TestHelper.ExpectedException <InvalidOperationException>( () => fileStream.BeginFlush(null, null), null); fileStream.EndFlush(result); Assert.IsFalse(result.CompletedSynchronously); Assert.AreEqual(3, opContext.RequestResults.Count); result = fileStream.BeginFlush( ar => waitHandle.Set(), null); Assert.IsTrue(result.CompletedSynchronously); waitHandle.WaitOne(); fileStream.EndFlush(result); Assert.AreEqual(3, opContext.RequestResults.Count); result = fileStream.BeginWrite( buffer, 0, buffer.Length, ar => waitHandle.Set(), null); waitHandle.WaitOne(); fileStream.EndWrite(result); wholeFile.Write(buffer, 0, buffer.Length); Assert.AreEqual(3, opContext.RequestResults.Count); result = fileStream.BeginCommit( ar => waitHandle.Set(), null); waitHandle.WaitOne(); fileStream.EndCommit(result); Assert.AreEqual(5, opContext.RequestResults.Count); } } Assert.AreEqual(5, opContext.RequestResults.Count); using (MemoryStream downloadedFile = new MemoryStream()) { file.DownloadToStream(downloadedFile); TestHelper.AssertStreamsAreEqual(wholeFile, downloadedFile); } } } finally { share.DeleteIfExists(); } }