CloudAppendBlob AppendTextAsync keeps overwriting my blob data, not appending it

I am attempting to use the new CloudAppendBlob in the latest C# Azure Storage library (5.0.0 stable and 5.0.1-preview) but my unit tests keep failing when using the AppendTestAsync method. Whenever I run my unit tests with the Async call (see below) the data appears to get overwritten, not appended i.e. the blob only contains the last string written to it.

await appendBlob.AppendTextAsync(base64EncodedBson + Base64Delimitter);

Using the call below works fine though, albeit I cannot take advantage of async code.

appendBlob.AppendText(base64EncodedBson + Base64Delimitter);

Am I missing something or is this a bug in the library? I tried searching on GitHub but nothing obvious shows itself:

Azure Storage repo on Github

I'm running the tests from a class library project in the latest version of VS2015.

August 24th, 2015 3:41pm

Hi Zhaoxing,

if you read my original posting, there is no exception generated and thus no stack trace to report. If you use the await appendBlob.AppendTextAsync method call the existing blob data gets overwritten (this is incorrect behaviour), but if you use the appendBlob.AppendText method call the data gets appended to the existing blob (as expected).

Run the code below as a console app and it demonstrates what I am seeing. You should see these results below, which shows the append async method has overwritten, not appended:

Append blob of name appendblob, length 200, contents: Appended Text No 0, Appended Text No 1, Appended Text No 2, Appended Text No 3, Appended Text No 4, Appended Text No 5, Appended Text No 6, Appended Text No 7, Appended Text No 8, Appended Text No 9,
Append blob of name appendblobasync, length 26, contents: Appended Async Text No 9,

Many Thanks,

Roger

private static void Main(string[] args)
{
    const string appendAsyncBlobName = "appendblobasync";
    const string appendBlobName = "appendblob";
    var connString = "Add your storage connection string here";
    var storageAccount = CloudStorageAccount.Parse(connString);
    var blobClient = storageAccount.CreateCloudBlobClient();

    // Retrieve a reference to a container. 
    var blockContainer = blobClient.GetContainerReference("appendblobtest");

    // Create the container if it doesn't already exist.
    blockContainer.CreateIfNotExists();

    // append data to the blob asynchronously
    AppendTextAsync(blockContainer, appendAsyncBlobName).Wait();

    // now do the same for the same but use the non-async method
    AppendTextNonAsync(blockContainer, appendBlobName);

    DisplayContainerContents(blockContainer);

    Console.ReadKey();
}

/// <summary>
/// Appends the text asynchronously
/// </summary>
/// <param name="blockContainer"></param>
/// <param name="appendAsyncBlobName"></param>
/// <returns></returns>
private static async Task AppendTextAsync(CloudBlobContainer blockContainer, string appendAsyncBlobName)
{
    var appendAsyncBlob = blockContainer.GetAppendBlobReference(appendAsyncBlobName);

    // delete the append blob
    appendAsyncBlob.CreateOrReplace();

    const int loopCount = 10;

    for (int i = 0; i < loopCount; i++)
    {
        await appendAsyncBlob.AppendTextAsync($"Appended Async Text No {i}, ");
    }
}

/// <summary>
/// Appends the text non-asynchronously
/// </summary>
/// <param name="blockContainer"></param>
/// <param name="appendBlobName"></param>
/// <returns></returns>
private static void AppendTextNonAsync(CloudBlobContainer blockContainer, string appendBlobName)
{
    var appendBlob = blockContainer.GetAppendBlobReference(appendBlobName);

    // delete the append blob
    appendBlob.CreateOrReplace();

    const int loopCount = 10;

    for (int i = 0; i < loopCount; i++)
    {
        appendBlob.AppendText($"Appended Text No {i}, ");
    }
}

/// <summary>
/// Displays the contest of the blobs in the container
/// </summary>
/// <param name="container"></param>
private static void DisplayContainerContents(CloudBlobContainer container)
{
    // Loop over items within the container and output the length and URI.
    foreach (IListBlobItem item in container.ListBlobs(null, true))
    {
        if (item is CloudAppendBlob)
        {
            var blob = (CloudAppendBlob) item;

            Console.WriteLine(
                $"Append blob of name {blob.Name}, length {blob.Properties.Length}, contents: {blob.DownloadText()}");
        }
        else if (item is CloudBlockBlob)
        {
            Console.WriteLine("This is a block blob");
        }
        else if (item is CloudPageBlob)
        {
            Console.WriteLine("This is a page blob");
        }
        else if (item is CloudBlobDirectory)
        {
            Console.WriteLine("This is a blob directory");
        }
    }
}


Free Windows Admin Tool Kit Click here and download it now
September 1st, 2015 6:10am

Hi Roger -

Thank you for reporting this - it is indeed a bug. We have posted an updated nuget package and update source code on GitHub.

http://blogs.msdn.com/b/windowsazurestorage/archive/2015/09/02/issue-in-azure-storage-client-library-5-0-0-and-5-0-1-preview-in-appendblob-functionality.aspx

Please let us know if you have any further issues.

Thanks

Jason

September 1st, 2015 11:19pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics