I'm using Azure BLOBs for the first time in a serious way. I have used it in the fast as a CDN and one thing I remember is it has significant latency at times. So I want to avoind that latency impacting the responsiveness of my pages.
So here's my use cases and my guess as to how to handle them. Any suggestions as to ways to reduce any delays the user will see? This is for a Blazor (server side) app.
Displaying their Avatar. I provide the url to the bitmap and the browser then will get it when it gets it. I know the dimensions so I can write the <img>
tag with the dimensions so the browser can reserve the correct space for it.
Update their Avatar. When they upload it, it's the same URI as I'm overwriting the existing bitmap. I think the approach here it so return control to the user immediately after calling BlobContainerClient.UploadBlobAsync(). And then get notified when the Task for that completes, switch to the UI thread, and then notify the Blazor renderer that the <img>
tag has changed.
Does this approach make sense? When the Task
completes, if the browser immediately asks for the UIR again, will it be the new value? And should I add a ?fubar=1234
to the url so it's a different value (for Azure BLOB server as well as the browser)?
Initialize the DxRichEdit component. I use the DevExpress DxRichEdit to provide a rich edit control. The content for this is a DOCX file saved as a BLOB (put a couple of pictures in the content and it rapidly becomes sizable). This may be more a DevExpress question, but I'm asking in terms of general approach to this. Can I call the DxRichEdit.LoadDocumentAsync() and not await its return. I pass it a Stream(blobUri) so I would need to save that stream and again, when the task it returns completes, dispose of it. So is that ok?
And more to the point, is it ok to have await OnInitializedAsync()
for my rendering complete where LoadDocumentAsync()
may not have completed yet? I can ask DevExpress for this specific case, but in general, is this asking for trouble? Or is this ok?
If I can't do this, should I then make this call the last thing in OnInitializedAsync()
so everything before that is rendered and visible to the user? Or do something so OnParameterSetAsync()
will be called and load it then?
And is this the best way to pass the content to LoadDocumentAsync:
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
Stream stream = await response.Content.ReadAsStreamAsync();
await richEditor.LoadDocumentAsync(stream)
Or this:
blobClient = container.GetBlobClient("thumbnail.png");
response = await blobClient.DownloadAsync();
await richEditor.LoadDocumentAsync(response.Content);
Write new RichEdit/Avatar when HandleValidSubmitAsync()
is called. So the user is done and clicks submit. BlobClient.UploadAsync()
is going to take a bit of time to complete. I assume everything needs to complete before the method completes. Everything else aside, if there's an error that has to be handled and usually displayed to the user.
But can I fire off each UploadAsync() as well as the database SaveChangesAsync() and then await that collection of tasks? Or something similar?
Anything I missed? Any common practices to best handle the large latency of talking to BLOB storage?