pjacko
pjacko

Reputation: 562

Blob does not exist when using BeginUploadFromStream

After I use CloudBlob.BeginUploadFromStream() method to upload a file, I later get a StorageClientException with StorageErrorCode.ResourceNotFound when trying to retrieve the file for a download. If I upload the same file using CloudBlob.UploadFromStream() method, then the blob DOES exist and i can download it.

here's my download code:

var client = _storageAccount.CreateCloudBlobClient();

var container = client.GetContainerReference(BLOB_CONTAINER_DOCUMENTS_ADDRESS);
container.CreateIfNotExist();

string blobName = id.ToString();

var newBlob = container.GetBlobReference(blobName);
if (newBlob.Exists())
{
    var stream = newBlob.OpenRead();
    return stream;
}
else
{

    throw new Exception("Blob does not exist!");
}

Exists is an extension method. I'm getting the StorageClientException with the error code ResourceNotFound when I use the BeginUploadFromStream() method

public static bool Exists(this CloudBlob blob)
{
    try
    {
        blob.FetchAttributes();
        return true;
    }
    catch (StorageClientException e)
    {
        if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
        {
            return false;
        }
        else
        {
            throw;
        }
    }
}

And my call to upload

var blob = container.GetBlobReference(blobName);

This will NOT throw an exception when i later check if the blob exists

blob.UploadFromStream(fileStream);

This will

AsyncCallback uploadCompleted = new AsyncCallback(OnUploadCompleted);
blob.BeginUploadFromStream(fileStream, uploadCompleted, documentId);

EDIT

As suggested, i didn't have a call to EndUploadFromStream() method. Here is my updated call to upload:

blob.BeginUploadFromStream(fileStream, uploadCompleted, blob);

And my handler

private void OnUploadCompleted(IAsyncResult result)
{
   var blob = (CloudBlob) result.AsyncState;
   blob.EndUploadFromStream(result);
}

Running this, the EndUploadFromStream() method throws a WebException with the msg: "The request was aborted: The request was canceled." The InnerException is "Cannot close stream until all bytes are written."

Anyone have any idea what's going on here?

Upvotes: 1

Views: 2114

Answers (2)

markti
markti

Reputation: 4518

What it sounds like is happening is IIS is cancelling the thread that is being initiated to make the BeginUploadFromStream. Since the storage API is really just manipulating a bunch of REST calls under the hood you can think of these storage calls as web service calls and not like traditional IO.

Check out this topic on HttpKeepAlives, this might solve your problem but as the article pointed out it may impact performance of your site. So you may want to add logic to only enable the keep alive for the requests that are performing the upload.

http://www.jaxidian.org/update/2007/05/05/8/

Upvotes: 0

Jeremy McGee
Jeremy McGee

Reputation: 25200

BeginUploadFromStream uploads the blob asynchronously, so your method proceeds while the blob uploads on a thread in the background. If the blob hasn't finished uploading -- or if Azure hasn't been told that the upload has completed -- you won't see the blob in storage. Only blobs uploaded through successfully completed transactions are visible.

Could you post the code for OnUploadCompleted?

It looks at first glance as if either the blob is still uploading -- or you've forgotten to call EndUploadFromStream() in your OnUploadCompleted method.

Upvotes: 2

Related Questions