NetMaui Blazor + Syncronisation Error in async + Android Release Build
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
- Testing Registration Submit
- Testing Post Object Create
- Testing post Method execute
- Testing pre unqiueness check
- Uniqueness check hit
- URL Generated
- HTTP Client Generated
- GET Executed, response {200, "Username uniqueness check passed"}
- 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.AsyncStateMachineBox
1[[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.AsyncStateMachineBox
1[[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.AsyncStateMachineBox
1[[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.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]].TrySetResult(Tuple2 ) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder
1[[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(Task
1 , Tuple2 ) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder
1[[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(Tuple
2 ) at Ghillie.API.UserManagement.CheckUserUniqueness(String username) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox
1[[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.AsyncTaskMethodBuilder
1.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(Thread ) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.AsyncStateMachineBox
1[[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)