Forum Xamarin.Forms

Getting an exception trown when calling PopAsync()

JKnottJKnott Member ✭✭✭
edited November 2020 in Xamarin.Forms

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!

Best Answer

Answers

  • JKnottJKnott Member ✭✭✭

    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.

  • JoeMankeJoeManke USMember ✭✭✭✭✭
    edited November 2020

    Why are you doing ConfigureAwaits in the click handler method at all?

  • JKnottJKnott Member ✭✭✭

    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.

  • JKnottJKnott Member ✭✭✭

    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!

Sign In or Register to comment.