/// <summary> /// Asynchronously invoke create on the given pageBlob. /// </summary> /// <param name="size">maximum size of the blob</param> /// <param name="pageBlob">The page blob to create</param> public void CreateAsync(long size, CloudPageBlob pageBlob) { Debug.Assert(waitingCount == 0, "Create should be called on blobs that don't already exist and exactly once"); // Asynchronously create the blob pageBlob.BeginCreate(size, ar => { try { pageBlob.EndCreate(ar); } catch (Exception e) { Trace.TraceError(e.Message); } // At this point the blob is fully created. After this line all consequent writers will write immediately. We just // need to clear the queue of pending writers. this.pageBlob = pageBlob; // Take a snapshot of the current waiting count. Exactly this many actions will be cleared. // Swapping in -1 will inform any stragglers that we are not taking their actions and prompt them to retry (and call write directly) int waitingCountSnapshot = Interlocked.Exchange(ref waitingCount, -1); Action <CloudPageBlob> action; // Clear actions for (int i = 0; i < waitingCountSnapshot; i++) { // inserts into the queue may lag behind the creation thread. We have to wait until that happens. // This is so rare, that we are probably okay with a busy wait. while (!pendingWrites.TryDequeue(out action)) { } action(pageBlob); } // Mark for deallocation for the GC pendingWrites = null; }, null); }