15

可能重复:
如何从 getter 或 setter 调用异步方法?

我正在尝试实现一个将在其中使用 Sqlite 等待的属性:

public int ID {
        get
        {
            if (_id != null)
            {
                return _id;
            }
            if (string.IsNullOrEmpty(ImageName))
            {
                return -1;
            }
            var query = CurrentConnection.Table<Image>().Where(i => i.ImageName == ImageName);
            var result = await query.ToListAsync();
            ...other code

但是,由于属性未设置为 await(尝试过,不起作用),我不能在属性内使用 await。

除了使用方法而不是属性之外,还有什么方法可以解决这个问题?

4

4 回答 4

12

不 - 没有异步属性之类的东西。即使您可以声明一个异步属性,也必须将其声明为返回值Task<int>而不是... 否则当您点击一个表达式int时您想要返回什么?await

假设您肯定想要异步行为,我会在这里强烈建议一种方法。GetIdAsync

于 2012-12-05T15:30:21.747 回答
11

C# 中不允许使用属性没有技术原因。async这是一个有目的的设计决策,因为“异步属性”是矛盾的。

属性应该返回当前值;他们不应该启动后台操作。

通常,当有人想要一个“异步属性”时,他们真正想要的是以下之一:

  1. 返回值的异步方法。在这种情况下,将属性更改为async方法。
  2. 可用于数据绑定但必须异步计算/检索的值。在这种情况下,要么使用async包含对象的工厂方法,要么使用async InitAsync()方法。数据绑定值将default(T)一直持续到该值被计算/检索。
  3. 创建成本高,但应缓存以备将来使用的值。在这种情况下,请AsyncLazy 从我的博客AsyncEx 库中使用。这会给你一个await能干的财产。
于 2012-12-05T15:40:54.473 回答
4

除了返回变量值之外,您不应该将属性 Getter 用于任何事情。

调用代码通常会对调用类时的期望做出性能方面的假设。

经验法则:

  • 属性意味着值的快速返回
  • 方法意味着或多或少的冗长操作

因此强烈建议不要将任何冗长的逻辑放入 getter。改用方法。

微软的 Rico Mariany在这里给出了一篇非常详细的文章:Properties Guidelines for Properties

于 2012-12-05T15:35:29.270 回答
0

如果使用 await,则将方法的其余部分转换为回调,这意味着您无法返回 int。您需要返回一个 Task<int>。目前也不支持在属性中使用 await,您需要将属性转换为返回 Task<int> 的“get”方法。

如果您想直接返回 int,而不是执行 await awaitable,请使用awaitable .Result。这将导致异步操作同步解决,允许您直接返回具体结果。

于 2012-12-05T15:31:19.153 回答