TLDR; Make sure all your async methods return a type of Task<something> and not just Task or Void! this will cause sporadic crashes of your application. Only use asyn void or async Task on event handlers.
Recently I worked on an app build in Xamarin and found myself in a nasty situation. My app would crash in the debugger and leave no trace what was going on. In the device Log I could find the following message:
Time Device Name Type PID Tag Message
04-08 18:22:28.908 nexus_api_27 Error 4058 DEBUG Abort message: ‘* Assertion at /Users/builder/jenkins/workspace/xamarin-android-d16-0/xamarin-android/external/mono/mono/mini/debugger-agent.c:4407, condition
is_ok (error)' not met, function:set_set_notification_for_wait_completion_flag, <strong>Could not execute the method because the containing type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder1[System.Collections.Generic.IEnumerable`1[T_REF]]’, is not fully instantiated. assembly: type: member:(null)
The nasty part was that when you step through the code in the debugger the application would just crash under your fingers and you could not step through the code that was causing this. And this message is useless as well since it does not show where things go wrong. Only stepping through the debugger revealed a part of the code where the debugger would exit without any message and the app crashed as well.
You can see at various placed more developers experience this issue. e.g.:
The code that was causing the crash looked as follows:
public override async Task<IEnumerable<Session>> GetItemsAsync(bool forceRefresh = false)
await InitializeStore().ConfigureAwait (false);
var sessions = await Table.OrderBy(s => s.StartTime).ToListAsync().ConfigureAwait(false);
var dataShare = Locator.Get<IPlatformSpecificDataHandler<Session>>();
if (dataShare != null)
The issue lies in the method calls that have await, but don’t expect a result.
The signatures of the methods InitializeStore(), PullLatestAsync() and AnnotateFavorites() all returned a Task, but not a Task<T>. This results in the fact that the method call is more or less fire and forget method and you don’t really have to wait for the result to be returned.
It is important that you change the method signatures to e.g. return a Task<bool> where the boolean is only signaling success or failure of the method call.
I was able to rewrite those methods to all return a boolean value and this resolved the issue of the method exiting without any results.
You can find more on best practices of using async and await here: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
Hope this helps you resolve this issue as well.
Leave a Reply