Xamarin - 在.Net标准库中使用httpClient

问题描述 投票:2回答:1

我创建了Xamarin项目,并为其添加了几个.Net标准类库(每层一个:数据访问,服务层等)。然后,在ServiceLayer项目中,我实现了一个方法,它从我的Web API(外部ASP Net Core项目)中获取数据。说到httpClient.GetAsync(),android app崩溃了。更重要的是,当我剪切这段代码并将其粘贴到默认的xamarin .Net标准库中时,一切正常。有任何想法吗?

代码在这里:

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

更新:

在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>();
}
c# rest xamarin dotnet-httpclient
1个回答
3
投票

问题出在async命令委托上

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

命令委托导致async void,它不会允许异常被捕获,因为它们被认为是火和忘记方法

参考Async/Await - Best Practices in Asynchronous Programming

创建一个事件和处理程序来管理异步调用

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));
} 

所以现在当调用该命令时,它将引发事件,异步处理程序可以正确地进行异步调用。

© www.soinside.com 2019 - 2024. All rights reserved.