在C#中使用await内部属性

时间:2012-12-05 15:27:59

标签: c# .net async-await c#-5.0

  

可能重复:
  How to call an async method from a getter or 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

但是,由于属性未设置为等待(尝试过,不起作用),我无法在属性中使用等待。

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

4 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:10)

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

属性应返回当前值;他们不应该开始背景操作。

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

  1. 返回值的异步方法。在这种情况下,请将属性更改为async方法。
  2. 可以在数据绑定中使用但必须异步计算/检索的值。在这种情况下,要么对包含对象使用async工厂方法,要么使用async InitAsync()方法。在计算/检索值之前,数据绑定值将为default(T)
  3. 创建成本高昂的值,但应缓存以供将来使用。在这种情况下,请使用AsyncLazy from my blogAsyncEx library。这将为您提供await能够获得的财产。

答案 2 :(得分:4)

除了只返回变量值之外,你不应该使用属性Getter。

调用代码通常会在调用类时对性能有所假设。

经验法则

  • 属性表示非常快速返回值
  • 方法暗示或多或少冗长的操作

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

微软的Rico Mariany 在此提供了一篇非常详细的文章:Performance Guidelines for Properties

答案 3 :(得分:0)

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

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