【问题标题】:sqlite-net and Async methods in xamarin formsxamarin 形式的 sqlite-net 和 Async 方法
【发布时间】:2021-07-30 03:12:59
【问题描述】:

正如这个问题的标题所述,我在 xamarin 表单 shell 应用程序中使用 sqlite-net nuget 包。我选择在我的应用程序中使用 sqlite API 的异步版本。我已经开发了一种方法,但我实际上不确定这是否正确。从技术上讲,它确实有效,并且可以完成我想要它做的事情,但我想知道这是否真的是最好的方法。这是有问题的方法

public async static Task<List<BPEntry>> GetAllBP()
{
    var query = database.Table<BPEntry>();   
    var result = await query.ToListAsync();
    return result;            
}

我感到困惑的是,当您在 query.ToListAsync() 上使用 await 运算符时,它会返回一个 List&lt;BPEntry&gt; 对象。

现在,我想将 List&lt;BPEntry&gt; 对象返回给调用方法,但由于我理解异步方法的工作方式,我不能直接将 List&lt;BPEntry&gt; 传回。

相反,我不得不返回包含列表的Task。这意味着我也必须将调用方法设为 I。

这对我来说似乎很奇怪。为什么我不能直接将 List&lt;BPEntry&gt; 对象传回非异步调用方法?

这几乎就像您解压缩操作以获取 List&lt;BPEntry&gt; 一样,但是您不必直接将其传回,而是必须将其包装在一个任务中。这对我来说似乎是多余的。

那么我这样做对吗?
有什么我遗漏的吗?
或者这就是异步方法在 C# 中的工作方式?

【问题讨论】:

  • 有一个口号:async all the way (1, 2),这意味着如果您在调用堆栈中的任何地方都使用异步,您可以充分利用异步模型。请阅读链接的文章。

标签: c# asynchronous xamarin.forms async-await task


【解决方案1】:

如果你想保持调用方法不异步,你有几个选择

首先是最简单的,只需从Task中获取Result属性,但这会导致死锁,阻塞当前线程直到返回结果,这是不好的。 您还有另一种选择,即将调用包装在 Task.Run() 中,然后从中获取 Result,这会将任务查询到另一个线程,因此不会阻塞。

没有理由不能使调用方法异步,如果您使方法异步,通常它之上的所有其他内容(调用它)也应该是异步的。

我们使用异步的原因是为了避免阻塞,通常在像 Xamarin.Forms 或 WPF 这样的 UI 应用程序中,例如允许在加载数据库时在屏幕上放置加载屏幕甚至动画,或者仍然让用户在此部分加载时处理应用程序的其他部分。

如果您不需要,那么只需使用同步 API。但是,如果您正在制作一个 Xamarin 应用程序,也就是移动应用程序,那么响应能力就非常重要,您不希望一个应用程序在整个屏幕上挂起,而没有任何迹象表明它仍在工作,并且正在努力工作。

考虑观看或阅读一些关于异步的教程以获取更多信息。

【讨论】:

  • 欢迎来到 StackOverflow。请尽量避免推荐使用.Result。请改用preferGetAwaiter().GetResult()
  • GetResult 只是不包装异常,我猜这更适合调试,但无论如何这两种做法都被认为是不好的做法。我会劝阻两者。
【解决方案2】:

你的从sqlite数据库获取数据的代码,我觉得是对的,但是你也可以试试下面的代码。

public async Task<List<Energys>> GetAlldata()
{
    var data = await conn.Table<Energys>().ToListAsync();
    return data;
}

private async void GetDataAsync()
{
    List<Energys> list = await GetAlldata();
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多