Xamarin - Использование httpClient в стандартной библиотеке .Net - PullRequest
0 голосов
/ 05 июля 2018

Я создал проект Xamarin и добавил в него несколько стандартных библиотек классов .Net (по одной для каждого уровня: доступ к данным, уровень обслуживания и т. Д.). Затем в проекте ServiceLayer я реализовал метод, который извлекает данные из моего веб-API (внешнего проекта ASP Net Core). Когда дело доходит до httpClient.GetAsync (), происходит сбой приложения Android. Более того, когда я вырезал этот кусок кода и вставил его в стандартную библиотеку xamarin .Net по умолчанию, все работает. Есть идеи?

Код здесь:

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

UPDATE:

В Viewmodel:

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

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

Обновление 2: Я изменил свой вызов асинхронного метода, как описано в первом ответе. Теперь, когда я пытаюсь выполнить код, приложение также падает, но я получаю сообщения об ошибках:

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)

Может быть, я что-то не так делаю с внедрением зависимостей в Unity, поэтому здесь регистрация классов сервисного уровня в App.xaml.cs

 protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<TestsListPage, TestsListViewModel>();
            containerRegistry.Register<IServiceLayerService, ServiceLayerService>();
}

1 Ответ

0 голосов
/ 05 июля 2018

Проблема с делегатом асинхронной команды

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

Результатом делегата команды является async void, который не позволяет перехватывать исключения, так как они считаются методами запуска и забывания

Ссылка Async / Await - Лучшие практики в асинхронном программировании

Создание события и обработчика для управления асинхронным вызовом

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

Обратите внимание, что обработчики событий являются единственным исключением из правила, которое позволяет async void

Подписаться на событие в конструкторе и вызвать событие в делегате команды

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

Так что теперь, когда команда вызывается, она вызывает событие и асинхронный обработчик может правильно выполнять асинхронные вызовы.

...