c# - Xamarin - 在 .Net 标准库中使用 httpClient
问题描述
我创建了 Xamarin 项目,并向其中添加了几个 .Net 标准类库(每一层一个:数据访问、服务层等)。然后,在 ServiceLayer 项目中,我实现了从我的 Web API(外部 ASP Net Core 项目)获取数据的方法。当涉及到 httpClient.GetAsync() 时,android 应用程序崩溃。更重要的是,当我剪切这段代码并将其粘贴到默认的 xamarin .Net 标准库中时,一切正常。有任何想法吗?
代码在这里:
HttpClient httpClient = new HttpClient();
var responseMessage = await httpClient.GetStringAsync(uri);
更新:
在视图模型中:
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>();
}
解决方案
问题在于异步命令委托
GetTestCommand = new DelegateCommand(async () => await GetTests());
命令委托产生一个async void
,它不允许捕获异常,因为它们被认为是触发和忘记方法
创建一个事件和处理程序来管理异步调用
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));
}
所以现在当命令被调用时,它将引发事件并且异步处理程序可以正确地进行异步调用。
推荐阅读
- python - 从网格中选择顶点以解析为脚本的参数
- r - Jupyter 笔记本:loadNamespace 中的“caret”的包或命名空间加载失败
- ios - if else 不适用于 Swift @IBaction UserDefault 用于检查登录
- php - 根据在数据库中的位置显示用户
- java - Java 消息驱动 Bean 覆盖
- java - 列表
RecyclerView 适配器中的数据设置 - javascript - 在 JS 中使用 fullcalendar 在鼠标悬停/输入事件时添加带有事件详细信息的弹出窗口
- java - WebElement 在运行时变为空
- wordpress - 如何在嵌入式报告中从 Google Data Studio 中删除页脚/水印?
- c - 我可以更改 pthread_create 以映射不在堆栈中的新线程吗?