What would cause a for / foreach loop to break without explicitly calling a break? - for-loop

I have a durable function that calls a method that simply adds a row to an efcore object. It doesn't call db save.
When I step through the code, and get to the for loop, it will immediately jump to the line after the for loop. If I step into the call to add the efcore object, and back to the for loop, it continues and loops to the next item. If I press F5 to let it go without debugging, it immediately "breaks" the for loop.
It jumps out of the for loop where i wrote //HERE!!!!!!
I'm pulling my hair out on this one.
obligatory code:
//foreach (stagingFileMap stagingFileMap in fileMaps)
foreach (stagingFileMap stagingFileMap in fileMaps)
{
if (ActivitySyncHelper.IsSyncCancelled(aso, _configuration))
{
break;
}
if (!string.IsNullOrEmpty(stagingFileMap.URL))
{
// Ensure the url is valid
try
{
string x = await GetTotalBytes(stagingFileMap.URL);
double.TryParse(x, out double fileByteCount);
if (fileByteCount > 0)
{
// Create or update the video in vimeo
if (string.IsNullOrEmpty(stagingFileMap.VimeoId))
{
// Azure won't be ready with its backups, so use confex host for video 'get'
string title = stagingFileMap.FileName;
if (stagingFileMap.FileName.Length > 127)
{
title = stagingFileMap.FileName.Substring(0, 127);
}
Video video = vimeoClient.UploadPullLinkAsync(stagingFileMap.URL, title, stagingFileMap.id, meetingIdFolder.Uri).Result;
stagingFileMap.VimeoId = video.Id.ToString();
stagingFileMap.VimeoId = video.Id.ToString();
//HERE!!!!!!
await syncLog.WriteInfoMsg($"Vimeo create {stagingFileMap.FileName}");
//HERE!!!!!!
}
else
{
// Attempt to pull the existing video and update it
if (long.TryParse(stagingFileMap.VimeoId, out long videoId))
{
Video video = vimeoClient.GetVideoAsync(videoId).Result;
if (video.Id.HasValue)
{
Video res = await vimeoClient.UploadPullReplaceAsync(stagingFileMap.URL, video.Id.Value, fileByteCount);
await syncLog.WriteInfoMsg($"Vimeo replace {stagingFileMap.FileName} id {res.Id}");
}
}
}
break;
}
}
catch (Exception ex)
{
// IDK what to do besides skip it and continue
// log something once logging works
await syncLog.WriteErrorMsg(aso, ex.Message);
await syncLog.Save();
continue;
}
// We need to save here requently because if there is big error, all the work syncing to vimeo will be desync with the DB
dbContext.Update(stagingFileMap);
await dbContext.SaveChangesAsync();
await syncLog.Save();
}
}
await dbContext.DisposeAsync();
public async Task WriteInfoMsg( string msg)
{
SyncAttemptDetail sad = new()
{
SyncAttemptId = _id,
Message = msg,
MsgLevel = SyncAttemptMessageLevel.Info,
AddDate = DateTime.UtcNow,
AddUser = "SYSTEM"
};
await _dbContext.SyncAttemptDetail.AddAsync(sad);
}

I'm dumb. Theres LITERALLY a break command in there.

The await will create a task and immediately return it (the debugger will follow this path too). The loop will continue in the task.
To attach the debugger to the task, add a break point after the await.

Related

Blazor Time Localisation

Hi i am in trouble with time, I want to display the time and update it in realtime
I already installed "Install-Package Blazored.Localisation"
below is the sample code
string currentLocalTime = "";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender) // Remove the firstRender check if you want the current local time displayed to continuously update.
{ // Leave the above firstRender check in place to ensure that the call to StateHasChanged() does not trigger an endless update loop.
var browserDateTime = await browserDateTimeProvider.GetInstance();
currentLocalTime = browserDateTime.Now.ToString();
StateHasChanged();
}
}
I realize that you can remove first render check if you want to continuously update.
Just remove If statement.
string currentLocalTime = "";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var browserDateTime = await browserDateTimeProvider.GetInstance();
currentLocalTime = browserDateTime.Now.ToString();
StateHasChanged();
}

Why CloudBlockBlob.Startcopyblob copies only 0bytes?

Sometimes I have a case that,copying from one blob to input assets blob copies only 0bytes...
I am retrying after the first try and also delay it for 80sec, but nothing changes...
The file is video and its size is 340mb... If you guys need any information, I can reply it...
private async Task CreateInputAssetBlobAsync(UploadRequest request)
{
var cloudBlobContainer = new CloudBlobContainer(request.InputAssetStorageUri);
var blockBlob = cloudBlobContainer.GetBlockBlobReference(request.BlobName);
var storageCredentials = new Microsoft.Azure.Storage.Auth.StorageCredentials(_apiAccess.TempBlobAccountName, _apiAccess.TempBlobContainerKey);
var tempBlobContainer = new CloudBlobContainer(new Uri(_apiAccess.TempBlobContainerAddress), storageCredentials);
var tempBlockBlob = tempBlobContainer.GetBlockBlobReference(request.BlobName);
try
{
await blockBlob.StartCopyAsync(tempBlockBlob);
do
{
if (blockBlob.CopyState.Status == CopyStatus.Pending)
await Task.Delay(1000);
await blockBlob.FetchAttributesAsync();
}
while (blockBlob.CopyState.Status != CopyStatus.Success);
await blockBlob.FetchAttributesAsync();
if (blockBlob.Properties.Length <= 0)
{
Task.Delay(80000);
await blockBlob.StartCopyAsync(tempBlockBlob);
do
{
if (blockBlob.CopyState.Status == CopyStatus.Pending)
await Task.Delay(1000);
await blockBlob.FetchAttributesAsync();
}
while (blockBlob.CopyState.Status != CopyStatus.Success);
}
return;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
You may want to take a look at the Remarks section of the Azure Blob API here
https://learn.microsoft.com/en-us/rest/api/storageservices/copy-blob
There are several remarks to be aware of with StartCopy blob.
“The Blob service copies blobs on a best-effort basis."
“For a block blob or an append blob, the Blob service creates a committed blob of zero length before returning from this operation."
“For all blob types, you can call Get Blob or Get Blob Properties on the destination blob to check the status of the copy operation. The final blob will be committed when the copy completes."
If the copies in your storage account are never completing, I would advise opening a support ticket with the details on the storage account, time and operation ids, etc.
Hope that is somewhat helpful.
Note: you should not use
do
{
if (blockBlob.CopyState.Status == CopyStatus.Pending)
await Task.Delay(1000);
await blockBlob.FetchAttributesAsync();
}
while (blockBlob.CopyState.Status != CopyStatus.Success);
but
do
{
await Task.Delay(1000);
await blockBlob.FetchAttributesAsync();
}
while (blockBlob.CopyState.Status == CopyStatus.Pending);
otherwise you will get an infinite loop if the copy has an error.
May be this is what happening in your case ?
In my code that works, I see that I retrieve a new CloudBlockBlob object once the copy is launched. Add the second line :
await tempBlockBlob.StartCopyAsync(blockBlob);
tempBlockBlob = (CloudBlockBlob)await tempBlobContainer.GetBlobReferenceFromServerAsync(request.BlobName);
and then do the fetchattribute and checks with tempBlockBlob. I got a 0 byte blob if I don't add the second line.

Dart component progress bar only updating at the end of loop

I'm developing an app in angular dart and trying to animate a progress bar which shows progress of a file upload. I'm simply parsing the JSON from the file, and sending them off to a service with a _service.create(....) method.
I've put all of this code in an async method which is called when my submit button is clicked:
void uploadFile() async {
submitButton.attributes.addAll({ 'disabled': '' });
progress.value = 0;
FileList files = input.files;
if (files.isEmpty) {
_handleError("No file selected");
//handle error, probably a banner
return;
}
File file = files.item(0);
FileReader reader = new FileReader();
//reader.result
reader.onLoadEnd.listen((e) async {
Map map = json.decode(reader.result);
var combinations = map['combinations'];
progress.max = combinations.length;
int loopCount = 0;
combinations.forEach((e) async {
await _service.create(VJCombination.fromJSON(e)).then((_) {
combinationCount++;
progress.value++;
loopCount++;
if (loopCount == combinations.length) {
submitButton.attributes.remove('disabled');
}
});
});
isLoadSuccessful = true;
});
reader.onError.listen((evt) => print(evt));
reader.readAsText(file);
progress.value = 10;
}
I'm getting the progress and the submitButton elements with the #ViewChild annotations:
#ViewChild('progress')
ProgressElement progress;
#ViewChild('submit')
ButtonElement submitButton;
The code works. The progress bar starts off empty, and after the file is read and the service gets the data, the progress bar is full.
My issue is that the UI is only updated after all of the combinations have been sent to the _service. So it seemingly goes from empty to full in one frame.
This code
combinations.forEach((e) async {
does not make sense, because forEach does not care about the returned Future
Rather use
for(var e in combinations) {
Not sure if this fixes your problem, but such code definitely needs to be changed.

Xamarin.ios iphone device Current location(street address)

public static async Task<Position> GetCurrentLocation()
{
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100;
if (!locator.IsGeolocationAvailable)
throw new NotSupportedException("Geolocation not available");
if (!locator.IsGeolocationEnabled)
throw new GeolocationException(GeolocationError.PositionUnavailable);
return await locator.GetPositionAsync(timeoutMilliseconds: 100000);
}
catch (Exception ex)
{
//TODO: Add error logging
return null;
}
}
on return await locator.GetPositionAsync(timeoutMilliseconds: 100000);
the thread exit and debugger not return but the output window shows the location correctly but didn't return to the code. What should be the possible reason for this break?
If I understand your question, you would like to know why your async code behaves the way it does?
Let's first get the terminology right: there is no thread that exits. Async/await is not about threads but about orchestrating asynchronous operations.
Your code returns at the await if the Task you are waiting for has not completed yet. Later, execution will then be picked up after the awaited code. In your case, the only thing that will happen is that the result of the task (= the location) will be returned.
So in any case, your method will exit:
either because the task is not complete yet
or because it is complete and you are using return

Await call to web service is stopping the execution flow of the program

I have the following code:
public async Task IntiateDataFetchingProcess(string[] args)
{
try
{
ProcessArgs(args);
Log.Information("Run Mode: {RunModeID}", RunModeID);
switch (RunModeID)
{
case RunModeType.A:
await MethodAAsync();
break;
case RunModeType.B:
await MethodBAsync();
break;
case RunModeType.C:
TestMethod();
break;
default:
break;
}
}
catch (Exception ex)
{
throw;
}
}
private async Task MethodBAsync()
{
Console.WriteLine(DateTime.Now.ToLongTimeString());
// Call to webservice to get the data
var response = await _service.GetDataAsync(input1, request);
Console.WriteLine(DateTime.Now.ToLongTimeString());
}
On debugging I found that the execution call comes to the below line (of method: MethodBAsync) and stops there.
var response = await _service.GetDataAsync(input1, request);
Can anyone help me to know is there anything that I am missing here.
Ah, your code is getting deadlocked!
You just need to add .ConfigureAwait(false); to each line that you are awaiting.
Example:
var response = await _service.GetDataAsync(input1, request);
becomes
var response = await _service.GetDataAsync(input1,
request).ConfigureAwait(false);
For more information on .ConfigureAwait(), Stephen Cleary wrote an awesome post on it.

Resources