Using Asynchronous Methods in the Storage Client Library
The Windows Azure SDK for .NET provides asynchronous methods for most storage operations. Asynchronous methods are more efficient than synchronous methods, especially in high-volume applications. Simultaneous calls to synchronous methods can use all of the available threads in the .NET Framework thread pool. The IsThreadPoolThread property of the CurrentThread static property reports whether or not a thread belongs to the managed thread pool.
Asynchronous methods in the Windows Azure SDK for .NET use a Begin* and End* naming convention. For example, the task performed by the synchronous UploadFromStream method can be performed asynchronously by passing a delegate to BeginUploadFromStream. The calling thread returns immediately. Next, a call to EndUploadFromStream returns when the task is complete. Either method can trigger an exception.
In addition to asynchronous methods, you can use these techniques to conserve managed threads:
-
Limit concurrent requests using a Semaphore, Interlocked, or Mutex.
-
Prepare test code that consumes threads from the managed thread pool. Ensure your application remains responsive when the thread pool is depleted.
The following code example specifies a delegate callback that completes the asynchronous operation.
static void ListContainersSegmentedAsync(Uri blobEndpoint, string accountName, string accountKey) { //Create client. CloudBlobClient blobClient = new CloudBlobClient(blobEndpoint, new StorageCredentialsAccountAndKey(accountName, accountKey)); //Call the async method (Begin Call and pass delegate). blobClient.BeginListContainersSegmented( ListContainersSegmentedAsyncCallback, blobClient); } static void ListContainersSegmentedAsyncCallback(IAsyncResult result) { CloudBlobClient blobClient = (CloudBlobClient)result.AsyncState; ResultSegment<CloudBlobContainer> resultSegment = blobClient.EndListContainersSegmented(result); //Enumerate containers. foreach (var container in resultSegment.Results) { Console.WriteLine(container.Name); } //Check whether the page is complete. if (resultSegment.HasMoreResults) { resultSegment = resultSegment.GetNext(); //Enumerate the containers. foreach (var container in resultSegment.Results) { Console.WriteLine(container.Name); } } }
The following code example specifies a lambda expression to complete the asynchronous operation. Note how the calling thread can use the resultSegment object after the lambda expression sets the ManualResetEvent.
public IEnumerable<CloudBlobContainer> ListContainersInSegmentsAsync() { ResultSegment<CloudBlobContainer> resultSegment = null; IAsyncResult asynResult = null; using (System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false)) { asynResult = BlobClient.BeginListContainersSegmented( result => { CloudBlobClient blobClient = (CloudBlobClient)result.AsyncState; resultSegment = blobClient.EndListContainersSegmented(result); evt.Set(); } , BlobClient); evt.WaitOne(); } return resultSegment != null && resultSegment.Results.Count<CloudBlobContainer>() > 0 ? resultSegment.Results : null; }
See Also
Reference
ThreadPoolIAsyncResult
Other Resources
The Managed Thread PoolImplementing the CLR Asynchronous Programming Model
