StorageException in DownloadToByteArrayAsync
See original GitHub issueI use DownloadToByteArrayAsync
to read from the end of an Append Blob, using this call:
var position = ...; // The value of 'blob.Properties.Length' at some point in the past
var context = new OperationContext();
context.SendingRequest += (sender, e) => { e.Request.Headers["if-match"] = "*"; };
var length = await blob.DownloadRangeToByteArrayAsync(
_buffer,
0,
position,
_buffer.Length,
new AccessCondition(),
new BlobRequestOptions(),
context,
cancel);
I expect this call to read any bytes past position
into _buffer
, and to return the number of bytes read. However, if another process is currently appending to the blob, this call sometimes throws an exception:
Microsoft.WindowsAzure.Storage.StorageException: Incorrect number of bytes received. Expected '3443580', received '3443752'
at Microsoft.WindowsAzure.Storage.Core.Util.StorageAsyncResult`1.End()
at Microsoft.WindowsAzure.Storage.Blob.CloudBlob.EndDownloadRangeToByteArray(System.IAsyncResult)
at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions+<>c__DisplayClass1`1.<CreateCallback>b__0(System.IAsyncResult)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
at AzureEventStore.Core.Drivers.AzureStorageDriver+<ReadAsync>d__15.MoveNext()
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
Top Results From Across the Web
ICloudBlob.DownloadToByteArrayAsync C# ...
DownloadToByteArrayAsync extracted from open source projects. ... ExpectedExceptionAsync<StorageException>(async () => await blob.
Read more >AzureBlobStorageService.cs
Sample code for azure blob storage comms using Xamarin as a client - Xamarin-Forms-Azure-Blob-Storage/Samples.XamarinForms.
Read more >CloudBlob.DownloadToByteArrayAsync Method
Initiates an asynchronous operation to download the contents of a blob to a byte array.
Read more >CloudBlockBlob.downloadToByteArray - Java
upload. Uploads the source stream data to the blob, using the specified lease ID, request options, and opera · deleteIfExists · getProperties ·...
Read more >Azure Blob download as byte array error "Memory Stream ...
The reason you're getting this error is because byte array's size can't be changed. If you wish to read directly in a byte...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thank you. Again, I wouldn’t really expect this to work on an arbitrary Block Blob (because the contents can change at random), but I do expect an Append blob to be append-only.
It was my understanding (but the documentation is vague on this point) that the
DownloadRangeAsByteArrayAsync
functions returned the number of bytes read because that number could be smaller than the requested length (in cases whereoffset + length
exceeds the length of the blob). If the expected behavior is that the call should fail if the range goes past the end of the blob (and therefore, the return value is always thelength
parameter), then I should probably look for another solution.My application reads from an Append Blob, polling for new data every few seconds (this new data is appended by other processes). I perform this call as part of the polling loop, each time with a
position
equal to the length of the blob and a_buffer.Length
of 4MB. The observed behavior is that:position
and performs the call again.StorageException
is thrown, but most concurrent writes do not cause the exception.So, it certainly looks like
DownloadRangeAsByteArrayAsync
behaves as I expect it to, outside of those rare exceptions being thrown, but I could be relying on unintentional (or unspecified) behavior.I am unable to provide a value of
position + _buffer.Length
that is smaller than the length of the blob, because I do not have access to the length of the blob. I could query for the blob metadata, but this would require two requests instead of only one in a rather latency-sensitive loop, for what I believe is a fairly simple “get new data” operation, so I would rather craft the HTTP GET request with anx-ms-range
manually if doing so is not possible through the C# API.Could I perhaps assume that if I do not provide the
length
parameter toDownloadRangeAsByteArrayAsync
, the function will not attempt to read more data than necessary to fill the provided buffer ?