2

I've created Xamarin project, and I added several .Net standard class libraries to it (one for each layer: data access, service layer etc.). Then, In ServiceLayer project, I implemented method, which fetch data from my Web API (external ASP Net Core project). When it comes to httpClient.GetAsync(), android app crash. What's more, when I cut this piece of code, and paste it in default xamarin .Net standard library, everything works. Any ideas?

Code is here:

HttpClient httpClient = new HttpClient();
var responseMessage = await httpClient.GetStringAsync(uri);

UPDATE:

In Viewmodel:

constructor(IServiceLayerService service){
        _ServiceLayerService = service;
        GetTestCommand = new DelegateCommand(async () => await GetTests());
        }     

        public async Task GetTests()
        {
            TestObservableCollection = new ObservableCollection<List<Test>>(await _ServiceLayerService.GetTestModels());
        }

Update 2: I've changed my async method call, in the way presented in first answer. Now, when I'm trying to execute code, app also crashes, but I'm receiving error messages:

07-05 14:39:04.518 F/        (25383): /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mono/mini/debugger-agent.c:4897: Could not execute the method because the containing type is not fully instantiated. assembly:<unknown assembly> type:<unknown type> member:(null) signature:<none>
07-05 14:39:04.518 F/libc    (25383): Fatal signal 6 (SIGABRT), code -6 in tid 25383 (com.companyname), pid 25383 (com.companyname)

Maybe I'm doing something wrong with Unity dependency injection, so here is registration of service layer classes in App.xaml.cs

 protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<TestsListPage, TestsListViewModel>();
            containerRegistry.Register<IServiceLayerService, ServiceLayerService>();
}
9
  • How and where is the code being called when it crashes? Are you making any blocking calls like .Result or .Wait()? Commented Jul 5, 2018 at 14:16
  • I'm injecting class from ServiceLayer project to ViewModel, and then, in command I'm executing it. Commented Jul 5, 2018 at 14:19
  • Show that. chances are you have an async void in the command that is not allowing you to catch the exception. Commented Jul 5, 2018 at 14:19
  • I've updated question with code Commented Jul 5, 2018 at 14:22
  • Yep GetTestCommand = new DelegateCommand(async () => await GetTests()); create an async void. Create an event handler and raise that in the command. Commented Jul 5, 2018 at 14:23

1 Answer 1

3

The problem is with the async command delegate

GetTestCommand = new DelegateCommand(async () => await GetTests());

The command delegate results in an async void, which wont allow exceptions to be caught as they are considered fire and forget methods

Reference Async/Await - Best Practices in Asynchronous Programming

Create an event and handler to manage the async call

private event EventHandler gettingTests = delegate { };
private async void OnGettingTests(object sender, EventArgs args) {
    try {
        await GetTests();
    } catch (Exception ex) {
        //...handle exception
    }
}

Note that event handlers are the one exception to the rule that allows async void

Subscribe to the event in the constructor and raise the event in the command delegate

constructor (IServiceLayerService service) {
    _ServiceLayerService = service;
    this.gettingTests += OnGettingTests;
    GetTestCommand = new DelegateCommand(() => gettingTests(this, EventArgs.Empty));
} 

So now when the command is invoked, it will raise the event and the async handler can make async calls correctly.

Sign up to request clarification or add additional context in comments.

3 Comments

I've changed my method call in the way You presented, but app is still crashing. I placed breakpoint, and noticed that app is crashing inside ServiceLayer project after GetStringAsync call. Unfortunetely without any exception. Last message from output is: xamarin-android/external/mono/mono/mini/debugger-agent.c:4897: Could not execute the method because the containing type is not fully instantiated. assembly:<unknown assembly> type:<unknown type> member:(null) signature:<none> (25383): Fatal signal 6 (SIGABRT), code -6 in tid 25383 (name), pid 25383 (name)
@Movart but now you can catch the exception to see what is the cause and trouble shoot. With async void delegate you were not able to do that.
Yes, I understand that, and thank you. Now I see those messages and I'm trying to fix them. I think, I'm doing something wrong with Unity dependency injection, but I can't figure out what

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.