Hello, I am trying to delete a record from a database then return the user to the last screen using this code
await Navigation.PopAsync(true).ConfigureAwait(false);
But every time I try to execute it I get the following exception thrown
**Java.Lang.IllegalStateException:** 'Must be called from main thread of fragment host'
The code I am executing is
/// <summary> /// Event handler for delete. /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> public async void BtnDeleteClicked(object sender, EventArgs e) { if (await DisplayAlert(StringTools.GetStringResource("szDeleteRecordTitle"), StringTools.GetStringResource("szDeleteRecord"), StringTools.GetStringResource("szYes"), StringTools.GetStringResource("szNo")).ConfigureAwait(true)) { if (viewModel.MyAmmo?.Id > -1) { if (viewModel.PhotosList?.Count > 0) { foreach (Photos p in viewModel.PhotosList) { await viewModel.PhotoRepo.RemoveItem(p).ConfigureAwait(false); } } await viewModel.AmmoRepo.RemoveItem(viewModel.MyAmmo).ConfigureAwait(false); } await Navigation.PopAsync(true).ConfigureAwait(false); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Manual release of managed resources. displayWarning.Dispose(); } // Release unmanaged resources. disposed = true; } }
The code in the repository is this
/// <summary> /// remove a record form the database. /// </summary> /// <param name="item"> </param> public async Task RemoveItem(AmmoLog item) { CreateConnection(); await connection.DeleteAsync(item).ConfigureAwait(true); OnItemRemoved?.Invoke(this, item); }
I cannot seem to figure out how to make this work.
The flow should be,
User views table of records.
Tap record to view details.
Tap Trash icon to delete.
Search for an remove images associated.
Remove record from DB.
Pop the view, returning to the original table.
Thanks for any help or advice!
Cheers!
If you suspect this might be a thread issue, try to call it on the main thread like:
Device.BeginInvokeOnMainThread(async () => { await Navigation.PopAsync(true); });
Answers
It seems that I was causing a thread issue by not having everything in ConfigureAwait = true.
If anyone else has any ideas on how to repair this, I'd love to hear it, but I figure it somewhat makes sense with the whole thread pool thing going on.
Why are you doing ConfigureAwaits in the click handler method at all?
I was under the impression that it was important for the thread continuity. If not, I'll just pull it. No need to over complicate the code after all! LOL
I just wanted to make sure that since I am waiting for other processes to complete their code, I didn't want to create a race condition where I could have intermittent problems with threads not cooperating.
If you suspect this might be a thread issue, try to call it on the main thread like:
Excellent! It turned out to not need the awaiting or thread controlling anyway, but this is definitely helpful for other places where I have had problems with processes running on the wrong threads!
Thanks!