NetMaui Blazor + Syncronisation Error in async + Android Release Build

Glenn Stretton 0 Reputation points
2024-12-10T14:55:32.4733333+00:00

I have a netmaui blazor hybrid (net8.0) app targeting Android and iOS.The registration form on my app uses API calls to my Azure backend to validate user entered data. This all works perfectly in debug mode. However, the process is failing in release builds.

I've added some logging and its contacting the backend fine, retrieving the data ok, but when I try to return from the method that makes the API call, it throws an exception.

Below is the failing part of the calling method, the api function and my log dump. Note my "TEST" logging which illustrates where the process is failing below.

private async void HandleSubmit()

{

   try

   {

       Logger.AddLog("1. Testing Registration Submit","TEST");

       PhoneFunctions.Vibrate();

       DialogService diag = new DialogService();

       UserManagement usermanager = new UserManagement();

       Logger.AddLog("2. Testing Post Object Create", "TEST");

       usermanager.Test(); // Test to make sure usermanager created ok

       Logger.AddLog("3. Testing post Method execute", "TEST");

       if (!acceptLicense)

       {

           await dlg.DisplayInfo("You must accept the license agreement to register a new user");

           return;

       }

       registationData.UserName = registationData.UserName.Trim();

       registationData.Email = registationData.Email.Trim();

       registationData.Password = registationData.Password.Trim();

       PreloadService.Show(SpinnerColor.Secondary, "Checking username");

       Logger.AddLog("4. Testing pre unqiueness check ", "TEST");

       Tuple<HttpStatusCode, string> usercheck = await usermanager.CheckUserUniqueness(registationData.UserName);

       Logger.AddLog($"10. Check Completed, result {usercheck.ToString()}", "TEST");

       PreloadService.Hide();

       if (usercheck.Item1 == HttpStatusCode.OK)

       {

       // DO SOME STUFF IF OK....

       }

    else

    {

        await diag.DisplayInfo("Register", "Username Check Failed - Please choose another username", "OK");

        

    }

}

catch (Exception ex)

{

    Logger.AddError(ex.ToString(), "Register.HandleSubmit");

}

}

public async Task<Tuple<HttpStatusCode, string>> CheckUserUniqueness(string username)

{

    Logger.AddLog("5. Uniqueness check hit", "TEST");

    try

    {

        string apiUrl = $"{APITools.GetAPIBaseAddress()}/Registration/UserUniqueCheck?Username=" + username;

        Logger.AddLog("6. URL Generated", "TEST");

        HttpClient httpClient = new HttpClient();

        Logger.AddLog("7.HTTP Client Generated", "TEST");

        string response = await httpClient.GetStringAsync(apiUrl);

        Logger.AddLog($"8. GET Executed, response {response.ToString()}", "TEST");

        Tuple<HttpStatusCode, string> result = Serialisation.DeserialiseToObject<Tuple<HttpStatusCode, string>>(response);

        Logger.AddLog($"9. Response Deserialised", "TEST");

        return result;

    }

    catch (Exception ex)

    {

        Logger.AddError(ex.ToString(), "CheckUserUniqueness Service Error");

        return new Tuple<HttpStatusCode, string>(HttpStatusCode.PreconditionFailed, "CheckUserUniqueness Service Error");

    }

}

// LOGGING DUMP

  1. Testing Registration Submit
  2. Testing Post Object Create
  3. Testing post Method execute
  4. Testing pre unqiueness check
  5. Uniqueness check hit
  6. URL Generated
  7. HTTP Client Generated
  8. GET Executed, response {200, "Username uniqueness check passed"}
  9. Response Deserialised

Then below below exception (Note: never hits Log.10). This only happens in a release build. In debug, the process works perfectly. Also seem to have the exact same error / issue in the login process which works in basically the same way,

System.NullReferenceException: Object reference not set to an instance of an object    at Ghillie.Pages.SocialPages.Register.HandleSubmit()Register.HandleSubmit    at Ghillie.Tools.Logger.AddError(String logText, String stack)    at Ghillie.Pages.SocialPages.Register.HandleSubmit()    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.Pages.SocialPages.Register.<HandleSubmit>d__15, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].ExecutionContextCallback(Object s)    at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.Pages.SocialPages.Register.<HandleSubmit>d__15, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].MoveNext(Thread )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.Pages.SocialPages.Register.<HandleSubmit>d__15, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].MoveNext()    at System.Threading.Tasks.AwaitTaskContinuation.<>c.<.cctor>b__17_0(Object state)    at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback , Object , Task& )    at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.Run(Task , Boolean )    at System.Threading.Tasks.Task.RunContinuations(Object )    at System.Threading.Tasks.Task.FinishContinuations()    at System.Threading.Tasks.Task1[[System.Tuple2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TrySetResult(Tuple2 )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1[[System.Tuple2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].SetExistingTaskResult(Task1 , Tuple2 )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1[[System.Tuple2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].SetResult(Tuple2 )    at Ghillie.API.UserManagement.CheckUserUniqueness(String username)    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Tuple2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.API.UserManagement.<CheckUserUniqueness>d__12, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].ExecutionContextCallback(Object s)    at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Tuple2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.API.UserManagement.<CheckUserUniqueness>d__12, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].MoveNext(Thread )    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox1[[System.Tuple`2[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Ghillie.API.UserManagement.<CheckUserUniqueness>d__12, Ghillie, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null]].MoveNext()    at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.<>c.<.cctor>b__8_0(Object state)    at Android.App.SyncContext.<>c__DisplayClass2_0.<Post>b__0()    at Java.Lang.Thread.RunnableImplementor.Run()    at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this)    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz)

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,636 questions
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,764 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,152 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.